克服JS奇怪的部分_ 關於非同步回呼

Huang Pei
4 min readApr 24, 2019

--

非同步(Asynchronous)

本筆記出自:JavaScript 全攻略:克服 JS 的奇怪部分

同步執行(synchronous execution)

One at a time

And in order…

按照順序一次執行一個,在JavaScript中一次只會發生一件事

非同步(Asynchronous)

More than one at a time

非同步表示在一個時間點不只一個。

可能有一段程式在執行時會開始執行另一段程式碼,然後又會再執行別的程式碼。

我流直接結論:JS可以不用一直等到一件事做完再做下一件事,他可以先把事件丟到事件佇列(Event Queue),先去執行別的事(執行堆疊Execution Stacks中的),等消化完執行堆疊後,再把事件佇列中的事拉出來完成。

所以非同步是假的!!JS不是一次做很多事,他只是調整了執行的順序,用同步的方式處理非同步事件

JS本身是同步的,它一次執行一行程式碼。

然而瀏覽器本身不是只有JS,還要和其他引擎(Rendering Engine, Http request..)相互連動運行,只有JS是同步的,那麼要如何和其他引擎及請求互相配合時又繼續跑程式碼呢?

原文:

//JS一邊要處理自己的程式碼,一邊還要處理一堆雜事,所以此時是非同步的The JavaScript engine has hooks where it can talk to the rendering engine and change what the web page looks like, or go out and request data.while it may be running asynchronously meaning that the rendering engine and the JavaScript engine and request are running asynchronously inside the browse.

JavaScript 引擎內的等待列則稱為事件佇列(event queue)

這裡面都是事件、事件通知,這些可能要發生的,所以當瀏覽器,在JavaScript引擎外的某處有一個需要被通知的事件,在 JavaScript 引擎裡會被放到佇列裡。

當執行堆是空的 JavaScript 才會注意事件佇列。

執行堆的函數尚未被消化,而EQ中有尚位處理的Click和HTTP
原本的執行堆被清空了,開始處理Click事件,將事件的函數拉出來執行,而HTTP待命中
//整段都很重要直到JavaScript已經逐行執行完程式,所以這不是真正的非同步,而是瀏覽器非同步的把東西放到事件佇列,但原本的程式仍然繼續一行行執行,執行堆空了,執行環境清除了都結束後,才會處理事件。

不太重要的課程範例:

落落長一堆只是要告訴我們,就算延遲了函式的時間(3秒,甚至就算是100秒也好),但在這3秒間就算怎樣狂點滑鼠,click event!的訊息也不會出現,要等三秒函式跑了execution stacks清光了,才會跑事件佇列內的click事件。

// long running function
function
waitThreeSeconds() {
var ms = 3000 + new Date().getTime();
while (new Date() < ms){}
console.log(‘finished function’);}
function clickHandler() {
console.log(‘click event!’);}
// listen for the click eventdocument.addEventListener(‘click’, clickHandler);
waitThreeSeconds();console.log(‘finished execution’);
_____
finished function
finished execution
.....三秒後之前點滑鼠的訊息才會跑出來
click event!

--

--

Huang Pei
Huang Pei

Written by Huang Pei

記錄用倉庫,歡迎指正。菜鳥前端,最菜的那種(超能力少女です)。

No responses yet