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

发布于 2022-09-06 15:16:48 字数 474 浏览 12 评论 0

打印出0~4我能想明白,为什么会最后一行打印的是5呢?5是什么时候传入的

const tasks = []; // 这里存放异步操作的 Promise
const 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));
}

// 异步操作完成之后,输出最后的 i
Promise.all(tasks).then(() => {
    setTimeout(() => {
        console.log(new Date, i);
    }, 1000);
});

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

甜是你 2022-09-13 15:16:48

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

当梦初醒 2022-09-13 15:16:48

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

欲拥i 2022-09-13 15:16:48

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

夏至、离别 2022-09-13 15:16:48

使用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,你就会看到报错的情况

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文