下面的示例代码让我感到困惑......
"use strict";
var filesToLoad = [ 'fileA','fileB','fileC' ];
var promiseArray = [];
for( let i in filesToLoad ) {
promiseArray.push(
new Promise( function(resolve, reject ) {
setTimeout( function() {
resolve( filesToLoad[i] );
}, Math.random() * 1000 );
})
);
}
Promise.all( promiseArray ).then(function(value) {
console.log(value);
});
我感到困惑的原因是我期望控制台上的输出是随机排序的。但我总是得到以下...
[ 'fileA', 'fileB', 'fileC' ]
至少可以说,这让我感到困惑,但真正让我摸不着头脑的是,当我将 let i 更改为 var i 时,我得到了以下结果。 ...
[ 'fileC', 'fileC', 'fileC' ]
作为最近才尝试完全理解 Promise 而不是很久以前开始使用 let 的人,我真的很困惑。
进一步阅读...
在得到很多很好的答案后,我重构了示例以摆脱循环和 i。对大多数人来说似乎很明显,但对我来说很有趣...
"use strict";
var filesToLoad = [ 'fileA','fileB','fileC' ];
function start( name ) {
return new Promise( function(resolve, reject ) {
setTimeout( function() {
resolve( name + '_done' );
}, Math.random() * 1000 );
});
}
Promise.all( filesToLoad.map(start) ).then(function(value) {
console.log(value);
});
最佳答案
此外,let
是 block 作用域,而 var
是函数作用域。
如果使用var i
:
触发函数超时后,循环完成,i 被设置为 2。所以它通过 filesToLoad[2]
解决了所有 setTimeout 函数。
如果使用let i
:
因为它是 block 作用域的,当函数被解析时它会记住声明 setTimeOut
时 i 的状态,所以当它被解析时它使用正确的 i 值。
关于使用 let i 时的输出顺序
Promise.all(Iterable<any>|Promise<Iterable<any>> input) -> Promise
给定一个 Iterable(数组是 Iterable),或一个 Iterable 的 promise,它产生 promises(或 promises 和值的混合),将 Iterable 中的所有值迭代到一个数组中并返回一个已实现的 promise当数组中的所有项目都满足时。 promise 的履行值是一个数组,其履行值位于原始数组的各个位置。如果数组中的任何 promise 被拒绝,则返回的 promise 将被拒绝,并附上拒绝原因。
因此,无论您的 promise 得到解决的顺序如何,promise.all 的结果将始终具有正确顺序的 promise 解决值。
关于javascript - 可以解释 let 和 var 的这种奇怪行为吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34064949/