每天記錄一點(diǎn)點(diǎn)....
setTimeout
面試官:“你知道定時(shí)器嗎?”我:“知道”面試官:“那你說(shuō)說(shuō)什么是定時(shí)器”我:“定時(shí)器是可以用setTimeout來(lái)實(shí)現(xiàn)的”面試官:“setTimeout(function () { console.log("1") },0);console.log("2");那你說(shuō)說(shuō)控制臺(tái)上輸出順序是什么识补?”
console.log('a');
setTimeout(function(){
console.log('b');
},0);
console.log('c');
console.log('d');
控制臺(tái)輸出:
a
c
d
b
我也不截圖了族淮。 知道為什么嗎,理論上他延遲時(shí)間為0不是應(yīng)該馬上執(zhí)行嗎凭涂,不是的祝辣。因?yàn)閟etTimeout運(yùn)行機(jī)制說(shuō)過(guò),必須要等到當(dāng)前腳本的同步任務(wù)和“任務(wù)隊(duì)列”中已有的事件切油,全部處理完以后蝙斜,才會(huì)執(zhí)行setTimeout指定的任務(wù)。也就是說(shuō)澎胡,setTimeout的真正作用是孕荠,在“任務(wù)隊(duì)列”的現(xiàn)有事件的后面再添加一個(gè)事件,規(guī)定在指定時(shí)間執(zhí)行某段代碼攻谁。setTimeout添加的事件稚伍,會(huì)在下一次Event Loop執(zhí)行。好吧戚宦,對(duì)事件循環(huán)不清楚的推薦看看阮一峰-avaScript 運(yùn)行機(jī)制詳解
原文鏈接:https://juejin.im/post/5aa4c47af265da239866e236
promise
打印以下程序的輸出:
new Promise(resolve => {
console.log(1);
resolve(3);
}).then(num => {
console.log(num)
});
console.log(2)
這道題的輸出是123个曙,為什么不是132呢?因?yàn)槲乙恢崩斫釶romise是沒有異步功能受楼,它只是幫忙解決異步回調(diào)的問(wèn)題垦搬,實(shí)質(zhì)上是和回調(diào)是一樣的,所以如果按照這個(gè)想法艳汽,resolve之后應(yīng)該會(huì)立刻then猴贰。但實(shí)際上并不是。難道用了setTimeout河狐?如果在promise里面再加一個(gè)promise:
new Promise(resolve => {
console.log(1);
resolve(3);
Promise.resolve().then(()=> console.log(4))
}).then(num => {
console.log(num)
});
console.log(2)
執(zhí)行順序是1243米绕,第二個(gè)Promise的順序會(huì)比第一個(gè)的早,所以直觀來(lái)看也是比較奇怪甚牲,這是為什么呢义郑?
Promise的實(shí)現(xiàn)有很多庫(kù)蝶柿,有jQuery的deferred丈钙,還有很多提供polyfill的,如es6-promise交汤,lie等雏赦,它們的實(shí)現(xiàn)都基于Promise/A+標(biāo)準(zhǔn)劫笙,這也是ES6的Promise采用的。
為了回答上面題目的執(zhí)行順序問(wèn)題星岗,必須得理解Promise是怎么實(shí)現(xiàn)的填大,所以得看那些庫(kù)是怎么實(shí)現(xiàn)的,特別是我錯(cuò)誤地認(rèn)為不存在的Promise的異步是怎么實(shí)現(xiàn)的俏橘,因?yàn)樽詈笠恍械腸onsole.log(2)它并不是最后執(zhí)行的允华,那么必定有某些類似于setTimeout的異步機(jī)制讓上面同步的代碼在異步執(zhí)行,所以它才能在代碼執(zhí)行完了之后才執(zhí)行寥掐。
原文鏈接 (更詳細(xì)的解釋):https://juejin.im/post/5aa3f7b9f265da23766ae5ae