非同步模式(Asynchronous)
概念:
不會去等待這個任務的結束才開始下一個任務,開啟過後就立即往後執行下一個任務,後續邏輯一般會通過回撥函式的方式定義。單執行緒的JavaScript語言需要通過赭紅模式去同時處理大量的耗時任務。對於開發者來說難點是程式碼的執行順序混亂
講解
console.log('gobal begin')
setTimeout(function timer1(){
console.log('timer1 invoke')
},1800)
setTimeout(function timer2(){
console.log('timer2 invoke')
setTimeout(function inner(){
console.log('inner invoke')
},1000)
},1000)
console.log('global end')
1、js執行引擎會把整體的程式碼全部載入進來
2、然後在呼叫棧(Call stack)當中壓入一個匿名(anonymous)的全域性呼叫,這個匿名的呼叫可以理解為把全部的程式碼放入到一個匿名的函式當中去執行,然後去逐行執行
3、呼叫棧中依次壓入上述程式碼去執行,呼叫棧中:
(anonymous) 逐行執行
console.log(‘global begin’) 執行 彈出
setTimeout(timer1) 執行
為timer1開啟一個倒數計時器 1.8stimer1放到一邊,這個倒數計時器是單獨工作不會受js單執行緒影響
彈出
setTimeout(timer2) 執行
為timer2開啟一個倒數計時器 1stimer2放到一邊
彈出
console.log(‘global end’) 執行 彈出
此時呼叫棧被清空 event loop開始發揮作用
event loop:負責監聽呼叫棧與訊息佇列,呼叫棧所有任務都結束了,event loop 會從訊息佇列中取出第一個回撥函式壓入到呼叫棧,此時訊息佇列為空,執行暫停下來了,等倒數計時結束後,timer2倒數計時先結束 放入到訊息佇列的第1位,timer1進入訊息佇列第2位,事件迴圈監聽到訊息佇列變化
開啟新一輪的呼叫棧
timer2壓入到呼叫棧 執行
setTimeout(inner) 執行
console.log(‘timer2 invoke’) 執行 彈出
為inner開啟一個倒數計時器 1sinner放到一邊
彈出
timer1 執行
console.log(‘timer1 invoke’) 執行 彈出
彈出
開啟新一輪的呼叫棧
inner壓入到呼叫棧 執行
console.log(‘inner invoke’) 執行 彈出
彈出
結束
注意:js時單執行緒,瀏覽器不是單執行緒。js呼叫的某些內部的api並不是單執行緒的
我們說的同步還是非同步不是指寫程式碼的方式,而是執行環境提供的API是以同步或非同步模式的方式工作
相關文章
- 設計模式學習
- flink1.10版local模式提交job流程分析
- jmeter-http代理伺服器,錄製指令碼,抓包-包含模式,過濾指定域名(url)資料
- 架構設計:微服務模式下,實現灰度釋出模式
- Golang三色標記、混合寫屏障GC模式圖文全分析
- C#設計模式-原型模式(Prototype Pattern)
- 12.java設計模式之代理模式
- 3. 目標精通--用java寫設計模式:依賴倒轉原則
- 設計模式-模板模式
- 將Vmware中配置成橋接模式
- Python3常用輸入模式:-輸入多組,固定組,多個輸入
- 09_單例模式
- 記一次使用策略模式優化程式碼的經歷
- 四種設計模式詳解
- Spark3.0.1各種叢集模式搭建
- PHP實現觀察者模式SplSubject SplObserver SplObjectStorage
- Java設計模式-17、直譯器模式-自定義語言的實現
- 同步模式(Synchronous)
- 遊戲程式設計模式學習:第一章命令模式
- 簡單工廠模式、工廠方法模式和抽象工廠模式有何區別?