JavaScript作為一種單線程的腳本語言,在執行過程中需要精妙地規劃,以避免如阻塞、死循環等不良情況出現。它的事件循環機制就是其中的一種解決方案。以上述代碼為例,我們可以清晰地理解JS執行代碼的順序。
// 這里是console.log的輸出結果 開始 開始Promise 結束 Promise結束 第一個定時器
根據以上代碼的執行輸出,JavaScript引擎在執行過程中將主線程分成了兩個部分,一部分是同步執行的任務棧,另一部分則是異步的任務隊列,其工作邏輯為:
- 在執行JS腳本時,將所有同步任務按照代碼順序放入任務棧中。
- 當執行到異步的任務時,比如setTimeout、Promise、AJAX,會將這些任務掛起,放在任務隊列中等待執行。
- 當所有同步任務執行完成后,JS引擎就會開始循環檢查任務隊列中是否有待處理的異步任務,如果有,則將其從任務隊列中取出,放入任務棧中,依次執行。
- 如此循環往復,直至任務隊列中無任務可執行。
這樣的過程可以幫助我們避免JS的阻塞,否則在同步任務執行期間,JS將無法處理異步任務,導致用戶界面假死、延遲響應等不良現象。有了事件循環機制,僅需執行少量的同步任務,就可以在后臺處理大量的異步任務,從而使整個應用程序變得更加高效和靈活。
setTimeout(function() { console.log('第一個定時器'); }, 0);
由于setTimeout是異步任務,故代碼中的第一個定時器輸出結果最后才被執行。需要注意的是,即便setTimeout中定義了0ms延遲,但實際上由于JS任務隊列和事件循環的特性, setTimeout仍然是在所有同步任務執行完成后才執行的。
new Promise(function(resolve) { console.log('開始Promise'); resolve(); }).then(function() { console.log('Promise結束'); });
Promise是ES6引入的語法糖,也屬于異步任務之一。在代碼中,Promise會被立即執行,執行期間發現自身無需掛起異步操作,因此會被放入同步任務隊列中。當所有同步任務執行完畢后,Promise的resolve方法才被調用,觸發其then方法內的代碼執行。
因此,在編寫JS應用程序時,我們應該合理利用事件循環機制,降低函數回調的嵌套層次,避免阻塞和延遲響應的影響。
上一篇css文件鼠標移動光標
下一篇div(grad r)