JavaScript范围陷阱与承诺
我有一个数组B包含这样的单词 B=[‘你好’、‘爱’、‘和平’] 我正在尝试创建承诺数组p:JavaScript范围陷阱与承诺,javascript,es6-promise,Javascript,Es6 Promise,我有一个数组B包含这样的单词 B=[‘你好’、‘爱’、‘和平’] 我正在尝试创建承诺数组p: for(var i=0;i如果将行初始化移到promise回调的函数范围内,不同的迭代将不会相互影响: B=['hello','love','peace']; P=[]; 对于(变量i=0;i{ var closureBinding=word;//ES3+ 设置超时(()=> 决心({ varBinding, closureBinding, letBinding, 康斯特宾, }), 200 );
for(var i=0;i如果将行
初始化移到promise回调的函数范围内,不同的迭代将不会相互影响:
B=['hello','love','peace'];
P=[];
对于(变量i=0;i */
将行移到承诺内
var B= ['hello', 'love', 'peace'] ;
var P = [] ;
for(var i = 0; i<B.length; i++){
var p = new Promise(function(resolve, reject){
var line = B[i];
setTimeout(function(){
resolve(line)},2000
);
})
P.push(p);
}
Promise.all(P).then(function(data){
console.log('data',data);
})
var B=['hello','love','peace'];
var P=[];
对于(var i=0;i如果使用es6,代码可能如下
让B=['hello','love','peace';
设P=[];
对于(var i=0;i您的问题是var
声明在JavaScript中被提升到最近的封闭函数块的顶部或文件的顶部。这意味着:
for (/* some loop */) {
var line = someValue();
}
实际上被翻译成:
var line;
for (/* some loop */) {
line = someValue();
}
您需要将var
绑定移动到new Promise
闭包中,或者使用ES2015+块绑定(let
或const
)
var words=['hello','love','peace'];
var承诺=[];
为了(让一个字一个字){
让letBinding=word;//ES2015+
const constBinding=word;//ES2015+
var varBinding=word;//ES3+
var p=新承诺(解决=>{
var closureBinding=word;//ES3+
设置超时(()=>
决心({
varBinding,
closureBinding,
letBinding,
康斯特宾,
}),
200
);
})
承诺推送(p);
}
Promise.all(promises).then(data=>console.log('data:',data));
其他es6答案都没有利用让在中为循环使用特殊的作用域规则
只需在for循环语句中使用let
(尝试运行它):
var B=['hello','love','peace',P=[];
for(设i=0;i设置超时(()=>resolve(B[i]));
P.push(P);
}
Promise.all(P).then(data=>console.log(data));//你好,爱,和平
或使用es7绑定语法:
Promise.all(['hello', 'love', 'peace'].map(::Promise.resolve)).then(::console.log)
太棒了!你能解释一下我的代码不工作的原因吗?区别在于作用域。var的作用域是最近的函数块,let的作用域是最近的封闭块(如果在任何块之外,两者都是全局的),它可以比功能块小。因此您创建了一个非常和平的承诺。除了使用let
之外,您还应该按照Timosta的建议将line
转换到promise
的执行器范围中。这里不需要闭包,因为line
只是一个辅助变量,不需要存在于父作用域中。
Promise.all(['hello', 'love', 'peace'].map(::Promise.resolve)).then(::console.log)