循环中如何存储Promise的resolve结果?及代码异常排查
关于循环中Promise结果存储及变量作用域问题的解决方案
嘿,这两个问题其实是关联在一起的,我来一步步帮你拆解!
问题2:为什么结果都是'test3'?
你遇到的是var变量的函数作用域陷阱。用var声明的a是函数级作用域,整个循环里共用同一个a变量。当3秒后setTimeout的回调执行时,循环早就结束了,此时a的值已经变成了3,所以所有Promise都会resolve出'test3'。
修复方案有这几种:
1. 用let代替var(最推荐)
let是块级作用域,每次循环都会创建一个新的a变量,每个setTimeout回调都会引用当前循环的那个a:
var overall = []; for(let a=0;a<3;a++){ var test_promise = new Promise(function(resolve,reject){ setTimeout(()=>{ console.log("looping: " + a); resolve('test' + a); },3000); }); overall.push(test_promise); } Promise.all(overall).then(function(value){ console.log(value); // 输出 ['test0','test1','test2'] });
2. 用立即执行函数(IIFE)创建闭包
手动为每个循环迭代创建独立的作用域,把当前的a值传递进去:
var overall = []; for(var a=0;a<3;a++){ (function(currentA) { var test_promise = new Promise(function(resolve,reject){ setTimeout(()=>{ console.log("looping: " + currentA); resolve('test' + currentA); },3000); }); overall.push(test_promise); })(a); } Promise.all(overall).then(function(value){ console.log(value); // 输出 ['test0','test1','test2'] });
3. 使用forEach循环
forEach的回调函数会为每个元素创建独立的作用域,避免共享变量的问题:
var overall = []; [0,1,2].forEach(function(a){ var test_promise = new Promise(function(resolve,reject){ setTimeout(()=>{ console.log("looping: " + a); resolve('test' + a); },3000); }); overall.push(test_promise); }); Promise.all(overall).then(function(value){ console.log(value); // 输出 ['test0','test1','test2'] });
问题1:如何在循环中将Promise的resolve结果存入数组?
你的思路其实是对的!核心步骤就是:
- 循环中创建Promise实例,把每个实例push到数组里(比如你的
overall数组) - 用
Promise.all(数组)等待所有Promise完成,它会返回一个新的Promise,当所有Promise都resolve后,会把所有resolve的结果按顺序组成数组,传递给then的回调函数
但要注意循环变量的作用域问题(就是问题2里踩的坑),确保每个Promise引用的是当前迭代的变量值,这样最终才能得到正确的结果数组。
内容的提问来源于stack exchange,提问作者alexlee11111
相关产品推荐
相关产品推荐

