引言
相信所有學(xué)過(guò) JavaScript 都知道它是一門(mén)單線程的語(yǔ)言,這也就意味著 JS 無(wú)法進(jìn)行多線程編程,但是 JS 當(dāng)中卻有著無(wú)處不在的異步概念 。在初期許多人會(huì)把異步理解成類(lèi)似多線程的編程模式,其實(shí)他們中有著很大的差別,要完全理解異步,就需要了解 JS 的運(yùn)行核心——事件循環(huán)(event loop)。在之前我對(duì)事件循環(huán)的認(rèn)識(shí)也是一知半解的,直到我看了 Philip Roberts 的演講 What the heck is the event loop anyway?,我才對(duì)事件循環(huán)有了一個(gè)全面的認(rèn)識(shí),所以我想寫(xiě)一篇介紹 JS 事件循環(huán)的文章,以供大家學(xué)習(xí)和參考。
一、為什么會(huì)有異步?
為什么 JS 當(dāng)中會(huì)有異步?我們想象一下,如果我們同步的執(zhí)行一下代碼會(huì)發(fā)生什么:
1 $.get(url, function(data) {2 //do something3 });
在我們使用 ajax 進(jìn)行通信的時(shí)候,我們都默認(rèn)了它是異步的,但是如果我們?cè)O(shè)置其為同步執(zhí)行,會(huì)發(fā)生什么?如果你自己寫(xiě)一個(gè)小的測(cè)試程序,將后臺(tái)代碼延遲5s你會(huì)發(fā)現(xiàn)瀏覽器會(huì)出現(xiàn)阻塞,直到 ajax 響應(yīng)了之后才會(huì)正常運(yùn)行。這便是異步模式要解決的首要問(wèn)題,如何使瀏覽器非阻塞的運(yùn)行任務(wù)。想象一下如果我們同步的執(zhí)行 ajax 請(qǐng)求的話,我們的等待的時(shí)間是一個(gè)未知數(shù),在網(wǎng)絡(luò)通信中可能很快也可能很慢,也可能永遠(yuǎn)也不會(huì)響應(yīng),這也就會(huì)導(dǎo)致瀏覽器會(huì)阻塞在一個(gè)未知的任務(wù)上面,這也是我們不希望看到的。所以我們希望有一種方式能夠異步的處理程序,我們并不需要關(guān)心一個(gè) ajax 請(qǐng)求會(huì)在何時(shí)完成,甚至它可以永遠(yuǎn)不會(huì)響應(yīng),我們只需要知道在請(qǐng)求響應(yīng)后該如何處理,并且在等待響應(yīng)的這段時(shí)間內(nèi)我們還可以做一些其他的工作。因此,便有了 JavaScript Event Loop。