2016-02-25 44 views
2

我對理解Q promise錯誤處理有些困惑。假設我有以下功能(僅用於演示):Q promise中的錯誤處理

function first() { 
    console.log('first'); 
    var done = Q.defer(); 
    done.resolve('first'); 
    return done.promise; 
} 

function second() { 
    console.log('second'); 
    var done = Q.defer(); 
    done.resolve('second'); 
    return done.promise; 
} 

function third() { 
    console.log('third'); 
    var done = Q.defer(); 
    done.resolve('third'); 
    return done.promise; 
} 

function fourth() { 
    console.log('fourth'); 
    var done = Q.defer(); 
    done.resolve('fourth'); 
    return done.promise; 
} 

function doWork() { 
    return first().then(function() { 
     return second(); 
    }).then(function() { 
     return third() 
    }).then(function() { 
     return fourth(); 
    }); 
} 

doWork().catch(function(err) { 
    console.log(err); 
}); 

一切都很順利。

現在,如果第二,第三第四功能,我已經得到了一些錯誤(由一個異步調用例如拋出),我可以抓住它優雅。

例如,如果在第二,第三或第四功能,我添加:

throw new Error('async error'); 

錯誤被捕獲。完善!

但是讓我困惑的是,如果在第一個函數中引發錯誤,那麼錯誤不會被捕獲,並且會破壞我的執行。

請別人告訴我爲什麼或我做錯了什麼?

非常感謝!

回答

4

承諾實現僅捕獲then回調中的例外情況。如果throwfirst中,該異常將會冒泡並且只會被try-catch語句捕獲。

這就是爲什麼異步(承諾返回)功能should never throw。相反,拒絕您要退回的承諾(done.reject(…)return Q.reject(…))。如果您不信任您的功能,您可以使用Promise.resolve().then(first).…來啓動您的連鎖店。

+2

你也可以開始與'q.fcall(第一)。然後(二)你的鏈...' – the4lt

+0

@ the4lt:是的,當然,我忘了這是一個具體的Q-問題。 'resolve()。then(...)'基本上是相同的,但是更加便攜。 – Bergi

+0

謝謝,現在我對它的工作原理很清楚。 – passkey1510

1

將在try塊中可以分解的邏輯和在catch塊中的錯誤包含在reject中。

var def = q.defer(); 
try { 
    // sync or async logic that can break 
} 
catch (ex) { 
    q.reject(ex); 
} 
return def;