ES5實(shí)現(xiàn)Promise(1) - 事件循環(huán)機(jī)制

? 因?yàn)楣緲I(yè)務(wù)面向國企以及傳統(tǒng)企業(yè)往果,所以代碼需要能夠在ie9以上運(yùn)行磷雇,所以在項(xiàng)目中無法用一些新技術(shù)羔砾。比如ES6的Promise魄幕,這個(gè)Promise真的是太好使了相艇,就跟便秘時(shí)使了開塞露一般。由于Promise太好使了纯陨,所以這兩天想著能不能用ES5實(shí)現(xiàn)Promise坛芽。在網(wǎng)上搜到了很多關(guān)于ES5實(shí)現(xiàn)Promise的文章,大部分都是說需要先明白JavaScript的時(shí)間循環(huán)機(jī)制翼抠。正好這塊我以前也不是非常明白咙轩,這次也正好仔細(xì)學(xué)習(xí)一下。


? JavaScript是一種單線程非阻塞的語言阴颖。單線程就是指代碼在執(zhí)行的時(shí)候活喊,只有一個(gè)線程來處理所有任務(wù)。非阻塞則指的是當(dāng)代碼在執(zhí)行一項(xiàng)無法立即返回結(jié)果的任務(wù)時(shí)量愧,就會(huì)先將這個(gè)任務(wù)掛起(pending)钾菊,待到其他這個(gè)任務(wù)返回結(jié)果后再按照一定的規(guī)則進(jìn)行操作帅矗。其實(shí)非阻塞就是用異步操作來完成的。用代碼可以表示成:

console.log(1);
setTimeout(function(){
    console.log(2);
},1000);
console.log(3);

? 這段代碼就是一個(gè)用異步操作來實(shí)現(xiàn)非阻塞的例子煞烫。代碼最后執(zhí)行結(jié)果是1 3 2浑此。這段代碼翻譯下來就是:首先在控制臺答應(yīng)1,打印完了之后就會(huì)執(zhí)行setTimeout方法滞详,這個(gè)方法是計(jì)時(shí)1000毫秒凛俱,這個(gè)1000毫秒就表示無法立即返回執(zhí)行的結(jié)果,所以此時(shí)會(huì)將setTimeout方法掛起料饥,掛起后setTimeout就會(huì)自顧自計(jì)時(shí)去了蒲犬。主線程將將setTimeout掛起后就繼續(xù)執(zhí)行后邊的語句去了,所以會(huì)在控制臺打印3“斗龋現(xiàn)在主線程上的任務(wù)都已經(jīng)處理完了暖哨,待setTimeout計(jì)完時(shí),就是執(zhí)行其回調(diào)函數(shù)凰狞,也就是在控制臺打印2。


? 說回JavaScript的事件循環(huán)沛慢。JavaScript執(zhí)行方法的時(shí)候赡若,會(huì)生成一個(gè)執(zhí)行環(huán)境,這個(gè)環(huán)境滿足了執(zhí)行這個(gè)方法的條件团甲。當(dāng)遇到一系列的方法后逾冬,就會(huì)將遇到的方法,依次添加到執(zhí)行棧躺苦。當(dāng)JavaScript第一次執(zhí)行時(shí)身腻,主線程會(huì)將所有的同步代碼按照執(zhí)行順序添加到執(zhí)行棧中。當(dāng)遇到的這個(gè)代碼是個(gè)方法時(shí)匹厘,就會(huì)將這個(gè)方法的執(zhí)行環(huán)境添加到執(zhí)行棧中嘀趟,然后進(jìn)入這個(gè)執(zhí)行環(huán)境,執(zhí)行方法中的所有代碼愈诚。執(zhí)行完了之后就會(huì)退出這個(gè)執(zhí)行環(huán)境并銷毀這個(gè)環(huán)境她按,然后就繼續(xù)執(zhí)行執(zhí)行棧中的下一個(gè)語句。當(dāng)主線程執(zhí)行代碼時(shí)遇到一個(gè)異步代碼時(shí)炕柔,就會(huì)將其掛起酌泰,期間繼續(xù)執(zhí)行執(zhí)行棧中的語句。當(dāng)這個(gè)掛起的方法執(zhí)行結(jié)束之后匕累,結(jié)束后的方法并不會(huì)立即添加到當(dāng)前的執(zhí)行棧中陵刹,而是將這個(gè)方法添加到了事件列表中,當(dāng)執(zhí)行棧中的代碼全部執(zhí)行完了之后欢嘿,主線程就會(huì)去事件列表里執(zhí)行里邊已經(jīng)有的方法衰琐。

console.log(1);         
setTimeout(function(){                   
    console.log(2000);
},2000);
setTimeout(function(){                  
    console.log(1000);
},1000);
console.log(3);                         

上邊這段代碼執(zhí)行時(shí)也糊,會(huì)先將console.log(1)添加到執(zhí)行棧,然后就遇到了第一個(gè)setTimeout碘耳,這是一個(gè)異步操作显设,所以將其掛起執(zhí)行,掛起后主線程就繼續(xù)往下執(zhí)行辛辨,又是一個(gè)異步操作捕捂,所以繼續(xù)掛起執(zhí)行,然后主線程繼續(xù)執(zhí)行斗搞,這會(huì)不是異步操作指攒,所以將這個(gè)console.log(3)添加到執(zhí)行棧。暫時(shí)先不管執(zhí)行棧里的代碼有沒有執(zhí)行僻焚,先看看之前掛起的兩個(gè)方法允悦,計(jì)時(shí)時(shí)間為1000毫秒的當(dāng)然先執(zhí)行完,這個(gè)時(shí)候就將其回調(diào)函數(shù)添加進(jìn)事件列表虑啤,等待執(zhí)行隙弛。然后計(jì)時(shí)2000毫秒的也計(jì)完時(shí)了,他的回調(diào)函數(shù)也就進(jìn)入了事件列表狞山。上邊也說了全闷,主線程會(huì)在將執(zhí)行棧里的代碼全部執(zhí)行完了之后再去執(zhí)行事件列表里的代碼。所以會(huì)先在控制臺打印1 3萍启,這時(shí)執(zhí)行棧里的代碼就全部執(zhí)行完了总珠,然后主線程就去執(zhí)行事件列表里的代碼。這時(shí)就會(huì)先將事件列表里的第一個(gè)代碼放到執(zhí)行棧里勘纯,再將第二個(gè)代碼放進(jìn)執(zhí)行棧局服。所以就先后打印出1000和2000。如果回調(diào)里套異步驳遵,異步的回調(diào)里套異步淫奔。這時(shí)候主線程就會(huì)在執(zhí)行棧和時(shí)間列表一直跑,從而形成了一個(gè)循環(huán)超埋,這就是事件循環(huán)機(jī)制了搏讶。


? 事件循環(huán)機(jī)制就是這樣。以上文字供我自己之后參考霍殴,摻雜大量個(gè)人理解和口語化表達(dá)媒惕,難免和官方有所偏差,一切以官方或大佬為準(zhǔn)来庭。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末妒蔚,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌肴盏,老刑警劉巖科盛,帶你破解...
    沈念sama閱讀 217,277評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異菜皂,居然都是意外死亡贞绵,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評論 3 393
  • 文/潘曉璐 我一進(jìn)店門恍飘,熙熙樓的掌柜王于貴愁眉苦臉地迎上來榨崩,“玉大人,你說我怎么就攤上這事章母∧钢耄” “怎么了?”我有些...
    開封第一講書人閱讀 163,624評論 0 353
  • 文/不壞的土叔 我叫張陵乳怎,是天一觀的道長彩郊。 經(jīng)常有香客問我,道長蚪缀,這世上最難降的妖魔是什么秫逝? 我笑而不...
    開封第一講書人閱讀 58,356評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮询枚,結(jié)果婚禮上筷登,老公的妹妹穿的比我還像新娘。我一直安慰自己哩盲,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評論 6 392
  • 文/花漫 我一把揭開白布狈醉。 她就那樣靜靜地躺著廉油,像睡著了一般。 火紅的嫁衣襯著肌膚如雪苗傅。 梳的紋絲不亂的頭發(fā)上抒线,一...
    開封第一講書人閱讀 51,292評論 1 301
  • 那天,我揣著相機(jī)與錄音渣慕,去河邊找鬼嘶炭。 笑死,一個(gè)胖子當(dāng)著我的面吹牛逊桦,可吹牛的內(nèi)容都是我干的眨猎。 我是一名探鬼主播,決...
    沈念sama閱讀 40,135評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼强经,長吁一口氣:“原來是場噩夢啊……” “哼睡陪!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,992評論 0 275
  • 序言:老撾萬榮一對情侶失蹤兰迫,失蹤者是張志新(化名)和其女友劉穎信殊,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體汁果,經(jīng)...
    沈念sama閱讀 45,429評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡涡拘,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了据德。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片鳄乏。...
    茶點(diǎn)故事閱讀 39,785評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖晋控,靈堂內(nèi)的尸體忽然破棺而出汞窗,到底是詐尸還是另有隱情,我是刑警寧澤赡译,帶...
    沈念sama閱讀 35,492評論 5 345
  • 正文 年R本政府宣布仲吏,位于F島的核電站,受9級特大地震影響蝌焚,放射性物質(zhì)發(fā)生泄漏裹唆。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評論 3 328
  • 文/蒙蒙 一只洒、第九天 我趴在偏房一處隱蔽的房頂上張望许帐。 院中可真熱鬧,春花似錦毕谴、人聲如沸成畦。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽循帐。三九已至,卻和暖如春舀武,著一層夾襖步出監(jiān)牢的瞬間拄养,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評論 1 269
  • 我被黑心中介騙來泰國打工银舱, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留瘪匿,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,891評論 2 370
  • 正文 我出身青樓寻馏,卻偏偏與公主長得像棋弥,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子诚欠,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評論 2 354

推薦閱讀更多精彩內(nèi)容