为什么在map异步循环中修改参数仅对首次异步函数调用生效?
运行结果原因解析
整个执行逻辑可以分为三个阶段拆解:
1. 同步执行阶段(对应输出3个连续的start)
array.map遍历数组时,传入的async函数里await关键字之前的所有代码都是同步立即执行的,三个迭代会按顺序执行以下逻辑:
- 打印
start - 给所有async函数共享的
user对象的id属性赋值为当前遍历的item - 调用
axios.get发送第一个请求,此时请求URL中的${user.id}会当场求值,因此三个请求分别访问的是/todos/1、/todos/2、/todos/3 - 遇到
await后,当前async函数挂起,让出线程执行下一个迭代的同步代码
三个迭代的同步逻辑全部执行完成后,user.id最后被赋值为3,后续没有代码再修改这个属性。
2. 第一批请求响应阶段(对应输出3个连续的middle)
三个异步axios请求返回响应后,对应async函数的后续逻辑才会恢复执行,首先打印middle。由于三个请求的响应时间接近,因此会连续输出三个middle。
3. 第二批请求执行与输出阶段(对应后续end开头的日志)
恢复执行后,代码走到第二个axios.get调用,此时拼接URL读取的是共享对象user.id,这个值已经固定为3,因此三个async函数发送的第二个请求全部访问/todos/3,所以所有end result 2的输出都是3。
而第一个请求的响应结果responseUser是每个async函数内部的私有变量,分别保存的是1、2、3对应的响应数据,最终end result的输出顺序由第一批请求的响应先后决定,示例中ID为3的请求最先返回,之后是2、最后是1,因此输出顺序为3、2、1。
内容的提问来源于stack exchange,提问作者Murilo Botelho
相关产品推荐
相关产品推荐

