課程視頻--循環中調用異步方法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說一下吧。
原始高清視頻下載
QQ答疑交流羣:
600633658
咱們的連接: