为何使用async/await与+=运算符时无法正确累加值?
问题解析:为什么sum的结果是2而不是3?
这段代码的核心问题出在异步执行时的变量快照和sum += await num的执行逻辑上,我们一步步拆解执行流程:
- 初始化全局变量
sum = 0。 - 调用
add(1):- 进入函数后,
sum += await num会被拆解为两步:先读取当前sum的值(此时是0)并暂存,然后遇到await num——因为num是普通数值,JS会自动把它包装成一个已resolve的Promise,函数暂停执行,把后续的赋值操作(sum = 暂存的0 + 1)放入微任务队列。
- 进入函数后,
- 紧接着调用
add(2):- 同样的逻辑,先读取当前
sum的值(此时还是0,因为第一个add的赋值还没执行)并暂存,然后await num触发函数暂停,把赋值操作(sum = 暂存的0 + 2)放入微任务队列。
- 同样的逻辑,先读取当前
- 主线程执行
setTimeout,把输出sum的回调放入宏任务队列(延迟100ms执行)。 - 主线程空闲后,开始按顺序处理微任务队列:
- 先执行第一个微任务:
sum = 0 + 1→sum变为1。 - 再执行第二个微任务:
sum = 0 + 2→sum被覆盖为2。
- 先执行第一个微任务:
- 100ms后,宏任务队列的回调执行,输出
sum的值为2。
如何得到预期的3?
如果想要sum最终为3,需要保证两个add函数的执行是串行的,或者在赋值时读取最新的sum值:
方法1:串行调用add函数
let sum = 0; async function add(num) { sum += await num; } // 用async/await保证串行执行 (async () => { await add(1); await add(2); setTimeout(() => console.log(sum), 100); // 输出3 })();
方法2:修改add函数,在await后读取最新sum
let sum = 0; async function add(num) { const value = await num; sum += value; // 此时读取的是最新的sum值 } add(1); add(2); setTimeout(() => console.log(sum), 100); // 输出3
内容的提问来源于stack exchange,提问作者Hao Wu
相关产品推荐
相关产品推荐

