跳到正文

副作用

Side Effect

中级通用

副作用(Side Effect)是代码运行时,除了返回结果,还改变了外部可观察的状态或触发了外部动作。识别它能帮你判断一次请求会不会写入数据库、发送邮件,以及重试后是否会重复执行。

你可能会说:「我想让 AI 帮我找出这个接口除了返回数据,还会改动哪里、触发什么操作。」

读之前建议先了解

动手看看

试算下单页面订单接口计算金额订单库未写入邮件服务未发送
1

用户先试算购物车金额,页面把商品和数量交给接口。这次只做计算,不提交订单。

要点

  1. 1

    看返回值之外发生了什么

    一个函数算出订单总价并返回数字,通常没有副作用;如果它同时保存订单、扣减库存或发送通知,这些就是副作用。判断时别只看返回值,还要看调用后外部有什么变化。

  2. 2

    副作用不等于出了问题

    你做支付接口时,记录支付结果就是业务目标,不是坏事。把它叫作副作用,是为了把“算出什么”和“实际改变了什么”分开看,这样我们才能安排执行顺序、测试失败情况。

  3. 3

    重试可能让动作发生两次

    假设接口已经发出优惠券,但响应在途中超时,客户端可能再次请求。如果发券藏在一段看似只负责计算的代码里,就容易重复发放。把这类动作找出来,才能决定怎样防重。

容易混淆的地方

副作用不等于状态变化:函数修改自己内部的临时变量,但外部观察不到,通常不算这里说的副作用。它也不等于数据库写入;发邮件、写文件、更新缓存同样可能是副作用。事务能协调一部分数据库操作的提交或回退,但不会自动撤回已经发出的邮件。

什么时候用

适合用

  • 设计下单接口时,列出写订单、扣库存、发通知等副作用,判断哪一步失败需要补救。
  • 排查请求超时后的重复操作时,找出重试会再次触发的扣款、发券或消息发送。
  • 写单元测试时,区分可以直接检验返回值的计算,以及需要验证外部调用的操作。

不适合用

  • 只是按商品价格和数量计算页面预估金额时,用纯计算函数即可,不需要写入订单或触发通知。
  • 用户只想预览导入文件会新增哪些记录时,先做解析和校验;确认导入前不需要实际写库。
  • 接口只负责读取并返回已有资料时,用只读查询即可,不必为了得到结果而修改业务数据。

练一练

你在做优惠券领取接口。调用方超时后会重试,但第一次请求可能已经发券。你会怎样处理发券这个动作?

让 AI 帮你做

请检查这个接口的副作用:列出它在返回结果之外会写入哪些数据、发送哪些消息或调用哪些外部服务;标明每个动作在超时、报错和重试时可能发生什么,并指出需要防重或补救的地方。先分析,不要直接改代码。

接下来学什么