視頻課程-循環(huán)中調(diào)用異步方法

冰山工作室出品

視頻課程-循環(huán)中調(diào)用異步方法

課程目錄

  1. 一個(gè)普通的for循環(huán)里面log一下 i
  2. for循環(huán)中有一個(gè)定時(shí)器
  3. 使用閉包
  4. 真實(shí)實(shí)作
  5. 使用ES6
  6. setTimeout 和 promise 的優(yōu)先級(jí)
  7. 使用ES7
  8. 關(guān)于我們

一個(gè)普通的for循環(huán)里面log一下 i


// 正常寫一個(gè)for循環(huán)輸出i
for (var i = 0; i < 5; i++) {
    console.log(i);
}
console.log(i);

假設(shè)你是一個(gè)面試者,你說(shuō)說(shuō)這幾行代碼會(huì)輸出什么?,你的內(nèi)心活動(dòng)會(huì)不會(huì)是“這特么不就是一個(gè)循環(huán)嗎?面試官既然這么問(wèn)老子(他還笑肯定不是好東西,肯定有陷阱),好好想一下,這好像和我看的那個(gè)閉包的題很像啊,這面試官是不是沒(méi)寫完?。吭趺崔k?!?/p>

如果稍微改動(dòng)一些尼,輸出結(jié)果又是什么?

for循環(huán)中有一個(gè)定時(shí)器


 for (var i = 0; i < 5; i++) {
    setTimeout(function () {
        console.log(new Date, i);
    }, 1000 * i);
}
console.log(new Date, i);

稍微加了點(diǎn)料(setTimeout)后,是不是看到這道題就舒服了,會(huì)不會(huì)想“’這不是老子背的最多的閉包問(wèn)題么,想一哈,setTimeout是會(huì)延遲執(zhí)行的所以外面的log會(huì)先執(zhí)行,i是用var聲明的,所以會(huì)變量提升,for循環(huán)里i最后執(zhí)行完i++,i變成了5,沒(méi)錯(cuò)了,老子這題得分了。

使用閉包


// 閉包
for (var i = 0; i < 5; i++) {
    ~function (j) {
        setTimeout(function () {
            console.log(new Date, j);
        }, 1000 * j);
    }(i);
}

順著上一個(gè)程式想“是不是還可以升華一下,我還能執(zhí)行出來(lái)0 1 2 3 4

真實(shí)實(shí)作


var roles = ['角色1', '角色2', '角色3'];
var arrayTest = [];
for (var i = 0; i < roles.length; i++) {
    !function (i) {
        $.get('https://www.baidu.com', { role: roles[i] }, function (res) {
            console.log(i);
            arrayTest[i] = i + roles[i] + res;
        })
    }(i);
}

如果你登錄一個(gè)后臺(tái)系統(tǒng),這個(gè)賬號(hào)下有不同角色(角色不固定,后期可能增加),傳不同角色進(jìn)行ajax請(qǐng)求得到相應(yīng)渲染頁(yè)面的數(shù)據(jù),但是這個(gè)接口只接收一個(gè)角色參數(shù), 那我們應(yīng)該怎么按我 們想要的順序獲取數(shù)據(jù)然后渲染頁(yè)面?

使用ES6


const tasks = [];
for (var i = 0; i < 5; i++) {
    ((j) => {
        tasks.push(new Promise((resolve) => {
            setTimeout(() => {
                console.log(new Date, j);
                resolve();
            }, 1000 * j); // 定時(shí)器的超時(shí)時(shí)間逐步增加
        }));
    })(i);
}

Promise.all(tasks).then(() => {
    setTimeout(() => {
        console.log(new Date, i);
    }, 1000);
});

當(dāng)你前面所有問(wèn)題都順利的回答完了,你想沒(méi)想過(guò)可能還有20%的人可以回答到你這種程度,怎么能變現(xiàn)的比他們牛逼一點(diǎn)尼?你可以考慮使用一下promise

setTimeout 和 promise 的優(yōu)先級(jí)


setTimeout(function () {
    console.log(1)
}, 0);
new Promise(function executor(resolve) {
    console.log(2);
    for (var i = 0; i < 10000; i++) {
        i == 9999 && resolve();
    }
    console.log(3);
}).then(function () {
    console.log(4);
});
console.log(5);

這道題應(yīng)該考察我 JavaScript 的運(yùn)行機(jī)制的,讓我理一下思路。
首先先碰到一個(gè) setTimeout,于是會(huì)先設(shè)置一個(gè)定時(shí),在定時(shí)結(jié)束后將傳遞這個(gè)函數(shù)放到任務(wù)隊(duì)列里面,因此開(kāi)始肯定不會(huì)輸出 1 。
然后是一個(gè) Promise,里面的函數(shù)是直接執(zhí)行的,因此應(yīng)該直接輸出 2 3 。
然后,Promise 的 then 應(yīng)當(dāng)會(huì)放到當(dāng)前 tick 的最后,但是還是在當(dāng)前 tick 中。
因此,應(yīng)當(dāng)先輸出 5,然后再輸出 4 。
最后在到下一個(gè) tick,就是 1 。
2 3 5 4 1

使用ES7


const sleep = (timeountMS) => new Promise((resolve) => {
    setTimeout(resolve, timeountMS);
});

(async () => { // 聲明即執(zhí)行的 async 函數(shù)表達(dá)式
    for (var i = 0; i < 5; i++) {
        await sleep(1000);
        console.log(new Date, i);
    }

    await sleep(1000);
    console.log(new Date, i);
})();

要是想給面試官留一個(gè)關(guān)注新技術(shù)的更牛逼印象,那就用es7說(shuō)一下吧。

關(guān)于我們

視頻課程在線觀看-----傳送門
視頻課程網(wǎng)盤地址-----傳送門 提取碼:ifv9
冰山社團(tuán)官網(wǎng)地址-----傳送門

如果觀看視頻或文檔后,你覺(jué)得有些收獲,愿意加入冰山社團(tuán)與我們一同成長(zhǎng),請(qǐng)進(jìn)入我們的官網(wǎng),點(diǎn)擊冰山社團(tuán),加入我們~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容