1. 程式人生 > >Node.js非同步程式設計帶來的難點

Node.js非同步程式設計帶來的難點

前言

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
})

我們在程式碼編寫過程中,自己編寫的非同步方法,也要遵循這樣一些規則。

  1. 必須執行呼叫者傳入的回撥函式
  2. 正確傳遞迴異常共呼叫者判斷

非同步方法程式碼例子如下

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等。

二者詳細的學習地址:

await

難點5 函式巢狀過深

多個回撥函式的互相依賴巢狀