【視頻教程】循環中調用異步方法-冰山工做室-沙翼-web前端

圖片描述

課程視頻--循環中調用異步方法html

最近遇到一道比較有趣的面試題,題目很簡單可是涉及到了不少小的知識點,還蠻有意思的。前端

一個普通的for循環輸出ies6

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

假設你是一個面試者,你說說這幾行代碼會輸出什麼?,你的心裏活動會不會是「這特麼不就是一個循環嗎?面試官既然這麼問老子(他還笑確定不是好東西,確定有陷阱),好好想一下,這好像和我看的那個閉包的題很像啊,這面試官是否是沒寫完啊?怎麼辦。」面試

若是稍微改動一些尼,輸出結果又是什麼?ajax

for循環中有一個定時器segmentfault

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

稍微加了點料(setTimeout)後,是否是看到這道題就舒服了,會不會想「’這不是老子背的最多的閉包問題麼,想一哈,setTimeout是會延遲執行的因此外面的log會先執行,i是用var聲明的,因此會變量提高,for循環裏i最後執行完i++,i變成了5,沒錯了,老子這題得分了」。promise

閉包解決。閉包

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

順着上一個程式想「是否是還能夠昇華一下,我還能執行出來0 1 2 3 4」異步

實做async

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

若是你登陸一個後臺系統,這個帳號下有不一樣角色(角色不固定,後期可能增長),傳不一樣角色進行ajax請求獲得相應渲染頁面的數據,可是這個接口只接收一個角色參數, 那咱們應該怎麼按咱們想要的順序獲取數據而後渲染頁面?

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); // 定時器的超時時間逐步增長
        }));
    })(i);
}
 
Promise.all(tasks).then(() => {
    setTimeout(() => {
        console.log(new Date, i);
    }, 1000);
});

當你前面全部問題都順利的回答完了,你想沒想過可能還有20%的人能夠回答到你這種程度,怎麼能變現的比他們牛逼一點尼?你能夠考慮使用一下promise

setTimeout和promise優先級

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

「這道題應該考察我 JavaScript 的運行機制的,讓我理一下思路。

首先先碰到一個 setTimeout,因而會先設置一個定時,在定時結束後將傳遞這個函數放到任務隊列裏面,所以開始確定不會輸出 1 。

而後是一個 Promise,裏面的函數是直接執行的,所以應該直接輸出 2 3 。

而後,Promise 的 then 應當會放到當前 tick 的最後,可是仍是在當前 tick 中。

所以,應當先輸出 5,而後再輸出 4 。

最後在到下一個 tick,就是 1 。

「2 3 5 4 1」

es7

const sleep = (timeountMS) => new Promise((resolve) => {
    setTimeout(resolve, timeountMS);
});
 
(async () => { // 聲明即執行的 async 函數表達式
    for (var i = 0; i < 5; i++) {
        await sleep(1000);
        console.log(new Date, i);
    }
 
    await sleep(1000);
    console.log(new Date, i);
})();

要是想給面試官留一個關注新技術的更牛逼印象,那就用es7說一下吧。


原始高清視頻下載

視頻講解--提取碼: ifv9

QQ答疑交流羣:
600633658

咱們的連接:

知乎 掘金 今日頭條 新浪微博 前端網 思否 簡書 B站

相關文章
相關標籤/搜索