Node.js非同步程式設計帶來的難點
阿新 • • 發佈:2018-12-18
前言
Node使得非同步程式設計首次出現在業務層面,它藉助非同步I/O模型和V8高效能引擎(事件迴圈機制),突破單執行緒的效能瓶頸,讓JavaScript在後端達到了實用價值。由於這種非同步程式設計的出現,對於node,也會出現一些難點。
難點1 異常處理
說到異常捕獲,相信大家都會想到try/catch/final,但是對於非同步程式設計這種方式並不適用。
虛擬碼如下:
try{
async(callback);
}catch(e){
}
假設async是一個非同步方法,呼叫async方法後,就會產生一個事件,事件(callback)會被放入該有的佇列中,到了下一次事件迴圈(Tick),會卻從佇列中取出,把回撥的內容傳遞給非同步函式。因為這種情況,對非同步方法進行try/catch操作只能捕獲當次事件迴圈內的異常,對callback執行回撥時候丟擲的異常是無能為力的。
由於這種異常捕獲的難點,Node在處理異常上形成了一種約定,將異常作為回撥函式第一個實參傳回,如果為空值,則表明非同步呼叫沒有異常丟擲。
非同步方法呼叫例子
async(function(err,result){
//TOO
})
我們在程式碼編寫過程中,自己編寫的非同步方法,也要遵循這樣一些規則。
- 必須執行呼叫者傳入的回撥函式
- 正確傳遞迴異常共呼叫者判斷
非同步方法程式碼例子如下
var async=function(callback){ process.nextTick=something; if(error){ return callback(error); } callback(null,results); });
難點2 阻塞程式碼
javascript程式設計沒有sleep()這樣的執行緒沉睡功能,要想實現延時操作只能使用setInterval()和setTimeout()這兩個函式。但是node是非同步的,這兩個函式並不阻塞後續程式碼的持續執行。(遇到這種睡眠一定時間的需求的時候,統一規劃業務邏輯之後,呼叫setTimeout()的效果會更好)
難點3 多執行緒程式設計
難點4 非同步轉同步
Node提供了絕大部分的非同步API和少量的同步API,但是非同步程式設計有的時候需要根據流程,將邏輯梳理成順序的同步形式,這種情況我們可以使用promise,和await等。
二者詳細的學習地址:
難點5 函式巢狀過深
多個回撥函式的互相依賴巢狀