正常情況下js都是順序執行的,但是也有很多場景下實際上是非同步操作:
1、定時器都是非同步操作
2、事件繫結都是非同步操作
3、AJAX中一般我們都採取非同步操作(也可以同步)
4、回撥函式可以理解為非同步(不是嚴謹的非同步操作) 剩下的都是同步處理
非同步操作產生的本質原因:js單執行緒event-loop執行模型
由於js會操作dom,而dom要展示出來就必須經過渲染,渲染的dom必須具有完整一致性,我們不能一邊渲染dom,同時js操作修改dom.
為了簡單地解決並行dom修改和dom渲染可能帶來的dom不一致的問題,提出了一個解決方案: 渲染+js順序執行於一個單執行緒中,js執行時渲染是停止的,渲染在執行時js是停止執行的。
在這種單執行緒模式下,如果js執行程式碼時間過長,比如請求網路下載大檔案,這時渲染就將停止,整個頁面處於無法接收任何ui輸入的狀態,也就是卡頓狀態,這將嚴重影響使用者的體驗。
正因為這樣,js引入了非同步操作的解決方案:不同步執行所有程式碼,而是僅同步執行部分程式碼,非同步的js程式碼則在合適的時機放入非同步loop佇列中,以便放入js主執行緒中執行。
比如:
$.ajax("http://www.baidu.com",{success(data){console.log(data)}})
在執行ajax請求後js引擎就繼續往下走,等待網路請求順利完成後,則將success回撥放到非同步佇列中,隨後在主執行緒中被執行。