javascript中同步和非同步
-
js是一門單執行緒的語言,不像Java,類繼承Thread再來個thread.start就可以開闢一個執行緒。js就像一條單一流水線,同一個時間只能做一個任務。
-
同步和非同步的差別在於這條流水線上各個流程的執行順序不同。
-
最基礎的非同步是setTimeout和setInterval函式,很常見,但很少有人知道這就是非同步。
-
<script type="text/javascript"> setTimeout(function(){ console.log("1") },0); console.log("2"); </script>
輸出順序是
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-4CEjkG46-1600846066722)(C:\Users\Beryl Zhang\AppData\Roaming\Typora\typora-user-images\image-20200923134823916.png)]
任務佇列,依次存放setTimeout中的function,在執行程式的時候,瀏覽器會預設setTimeout以及ajax請求這一類的方法都是耗時程式(儘管可能不耗時),將其加入一個佇列中,該佇列是一個儲存耗時程式的佇列,在所有不耗時程式執行過後,再來依次執行該佇列中的程式。儘管setTimeout的time延遲時間為0,其中的function也會被放入一個佇列中,等待下一個機會執行,當前不需要加入佇列中的程式必須在佇列的程式完成之前完成。
-
js是單執行緒,意味著所有的任務需要排隊,等一個任務結束,才會執行後一個任務。如果前一個任務耗時很長,後一個任務就不得不一直等著。於是有了任務佇列
如果排隊是因為計算量大,CPU忙不過來,倒也算了,但是很多時候CPU是閒著的,因為IO裝置(輸入輸出裝置)很慢(比如Ajax操作從網路讀取資料),不得不等著結果出來,再往下執行。於是JavaScript語言的設計者意識到,這時主執行緒完全可以不管IO裝置,**掛起處於等待中的任務,先執行排在後面的任務。**等到IO裝置返回了結果,再回過頭,把掛起的任務繼續執行下去。
-
所有任務可以分為兩種
-
同步任務(synchronous),指的是在主執行緒上排隊執行的任務,只有前一個任務執行完畢,才能執行後一個任務
-
如果在函式返回結果的時候,呼叫者能夠拿到預期的結果(就是函式計算的結果),那麼這個函式就是同步的。即使比較慢也會等他執行完。
console.log('hello');
-
-
非同步任務(asynchronous),指的是不進入主執行緒,而進入任務佇列(task queue)的任務,只有等主執行緒任務執行完畢,任務佇列開始通知主執行緒,請求執行任務,該任務才會進入主執行緒執行
- 在函式返回的時候,呼叫者還不能立即得到預期結果,而是將通過一定手段得到(例如回撥函式),例如ajax操作。呼叫者不必主動等待,當被呼叫者得到結果之後會通過回撥函式主動通知呼叫者。
-
-
非同步執行機制
- 所有的同步任務都在主執行緒上執行,形成一個執行棧(execution context stack)
- 主執行緒之外,還存在一個任務佇列task queue。只要非同步任務有了執行結果,就在任務佇列之中放置一個事件。
- 一旦執行棧中的所有同步任務執行完畢,系統就會讀取任務佇列,看看裡面有哪些事件,對應的非同步任務結束等待狀態進入執行棧開始執行。
- 主執行緒不斷重複上面的第三步。
-
IO裝置完成一項任務,就在任務佇列中新增一個事件,表示相關的非同步任務可以進入執行棧了,主執行緒讀取任務佇列,就是讀取裡面有哪些事件。
-
任務佇列中的事件,除了IO裝置的事件以外,還包括一些使用者產生的事件(比如滑鼠點選、頁面滾動等),比如 $(selectot).click(function),這些都是相對耗時的操作。只要指定過這些事件的回撥函式,這些事件發生時就會進入任務佇列,等待主執行緒讀取。
-
回撥函式,就是那些會被主執行緒掛起來的程式碼,$(selectot).click(function)中的function就是一個回撥函式。非同步任務必須指定回撥函式(callback),當主執行緒開始執行非同步任務,就是執行對應的回撥函式。例如ajax的success,complete,error也都指定了各自的回撥函式,這些函式就會加入任務佇列中等待執行。
-
js是單執行緒是因為瀏覽器在執行時只開一個js直譯器,有兩個執行緒操作DOM瀏覽器就暈了。瀏覽器不是單執行緒的,一些IO操作,定時器的計時和事件監聽是由其他執行緒完成的。
相關文章
- 同步、非同步、阻塞和非阻塞非同步
- 非同步和非阻塞非同步
- Socket程式設計中的同步、非同步、阻塞和非阻塞(轉)程式設計非同步
- ♻️同步和非同步;並行和併發;阻塞和非阻塞非同步並行
- 同步非同步,阻塞非阻塞非同步
- 非同步、同步、阻塞、非阻塞非同步
- 同步、非同步、阻塞、非阻塞非同步
- 同步非同步 與 阻塞非阻塞非同步
- 理解阻塞、非阻塞、同步、非同步非同步
- 同步、非同步,阻塞、非阻塞理解非同步
- 同步、非同步、阻塞與非阻塞非同步
- [轉]阻塞/非阻塞與同步/非同步非同步
- 同步與非同步 阻塞與非阻塞非同步
- javascript中的非同步 macrotask 和 microtask 簡介JavaScript非同步Mac
- Java 非阻塞 IO 和非同步 IOJava非同步
- 從同步原語看非阻塞同步以及Java中的應用Java
- 如何解讀 Java IO、NIO 中的同步阻塞與同步非阻塞?Java
- AJAX 非同步(JavaScript 和 XMLHTTP)非同步JavaScriptXMLHTTP
- 同步、非同步、阻塞、非阻塞的區別非同步
- 對執行緒、協程和同步非同步、阻塞非阻塞的理解執行緒非同步
- 徹底搞懂同步非同步與阻塞非阻塞非同步
- IO - 同步 非同步 阻塞 非阻塞的區別非同步
- 同步、非同步、阻塞、非阻塞的簡單理解非同步
- 同步與非同步、阻塞與非阻塞的理解非同步
- java同步非阻塞IOJava
- Javascript的非同步和回撥JavaScript非同步
- 同步和非同步非同步
- 同步阻塞、同步非阻塞、多路複用的介紹
- Javascript中的非同步程式設計JavaScript非同步程式設計
- JS 非同步和同步JS非同步
- 阻塞非阻塞和同步非同步的區分 參考一些書籍非同步
- 大白話搞懂什麼是同步/非同步/阻塞/非阻塞非同步
- socket阻塞與非阻塞,同步與非同步、I/O模型非同步模型
- 網路IO之阻塞、非阻塞、同步、非同步總結非同步
- 你不知道的JavaScript 同步非同步JavaScript非同步
- 如何給女朋友解釋什麼是IO中的阻塞、非阻塞、同步、非同步?非同步
- iOS中通知非同步?同步?iOS非同步
- JavaScript非同步史JavaScript非同步