
視頻課程-循環(huán)中調(diào)用異步方法
課程目錄
- 一個(gè)普通的for循環(huán)里面log一下 i
- for循環(huán)中有一個(gè)定時(shí)器
- 使用閉包
- 真實(shí)實(shí)作
- 使用ES6
- setTimeout 和 promise 的優(yōu)先級(jí)
- 使用ES7
- 關(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),加入我們~