鍍金池/ 問答/HTML/ 為什么這個(gè)promise最后一個(gè)打印結(jié)果是5?

為什么這個(gè)promise最后一個(gè)打印結(jié)果是5?

打印出0~4我能想明白,為什么會(huì)最后一行打印的是5呢?5是什么時(shí)候傳入的

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);
});
回答
編輯回答
故人嘆

for循環(huán)和Promise.all作用域在同一級(jí) 所以i是5

2018年5月29日 20:05
編輯回答
忠妾

i是全局變量,for循環(huán)最后一次,i++,盡管跳出了循環(huán),但i變成了5,promise.all().then()里面那個(gè)setTimeout里打印了i,所以最后就變成了5

2018年9月5日 23:49
編輯回答
卟乖

你打印的是全局變量i 而這個(gè)變量在for循環(huán)執(zhí)行完后就是5了

2017年8月3日 18:06
編輯回答
萌吟

使用var聲明的變量是沒有局部作用域的概念,只有函數(shù)作用域。

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

因?yàn)閕是在最外層作用域的,而then中的回調(diào)是在所有promise都resolve之后才執(zhí)行的,這是 i 已經(jīng)被賦值為5,所以輸出5.
如果使用let聲明i,你就會(huì)看到報(bào)錯(cuò)的情況

2018年1月17日 09:42