javascript - 可以解释 let 和 var 的这种奇怪行为吗?

标签 javascript node.js ecmascript-6 es6-promise

下面的示例代码让我感到困惑......

"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);
});

最佳答案

是因为闭包。了解一下 herehere .

此外,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/

相关文章:

javascript - JS : Replace some fields of an specific object inside of an array

javascript - 如何克服本地机器中的 http 请求状态为零

javascript - 使用Node.js同步下载N个远程文件

javascript - ES6 类扩展了 Socket IO

javascript - 获取数据时如何处理表名中的百分号

javascript - 如何读取流.pipe(myfunction())

javascript - 触发按钮单击文本框中的 Enter 键丢失其值

javascript - JScript确认无限循环?

javascript - jQuery 定位正确的单选按钮没有响应

node.js - 将 yarn.lock 同步回 package.json 并锁定