为了账号安全,请及时绑定邮箱和手机立即绑定

为什么这个promise最后一个打印结果是5?

为什么这个promise最后一个打印结果是5?

哔哔one 2019-03-14 13:12:50
打印出0~4我能想明白,为什么会最后一行打印的是5呢?5是什么时候传入的const tasks = []; // 这里存放异步操作的 Promiseconst output = (i) => new Promise((resolve) => {    setTimeout(() => {        console.log(new Date, i);        resolve();    }, 1000 * i);});// 生成全部的异步操作for (var i = 0; i < 5; i++) {    tasks.push(output(i));}// 异步操作完成之后,输出最后的 iPromise.all(tasks).then(() => {    setTimeout(() => {        console.log(new Date, i);    }, 1000);});
查看完整描述

4 回答

?
波斯汪

TA贡献1811条经验 获得超4个赞

你打印的是全局变量i 而这个变量在for循环执行完后就是5了


查看完整回答
反对 回复 2019-03-17
?
繁星点点滴滴

TA贡献1803条经验 获得超3个赞

i是全局变量,for循环最后一次,i++,尽管跳出了循环,但i变成了5,promise.all().then()里面那个setTimeout里打印了i,所以最后就变成了5


查看完整回答
反对 回复 2019-03-17
?
潇湘沐

TA贡献1816条经验 获得超6个赞

for循环和Promise.all作用域在同一级 所以i是5


查看完整回答
反对 回复 2019-03-17
?
喵喔喔

TA贡献1735条经验 获得超5个赞

使用var声明的变量是没有局部作用域的概念,只有函数作用域。


    for (var i = 0; i < 5; i++) {

        tasks.push(output(i));

    }

    // 异步操作完成之后,输出最后的 i

    Promise.all(tasks).then(() => {

        setTimeout(() => {

            console.log(new Date, i);

        }, 1000);

    });

这种写法和下面的写法是一样的效果:


    var i = 0

    for (; i < 5; i++) {

        tasks.push(output(i));

    }

    // 异步操作完成之后,输出最后的 i

    Promise.all(tasks).then(() => {

        setTimeout(() => {

            console.log(new Date, i);

        }, 1000);

    });

因为i是在最外层作用域的,而then中的回调是在所有promise都resolve之后才执行的,这是 i 已经被赋值为5,所以输出5.

如果使用let声明i,你就会看到报错的情况


查看完整回答
反对 回复 2019-03-17
  • 4 回答
  • 0 关注
  • 619 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信