2016-11-17 173 views
3

我正在使用異步瀑布。當我的一個函數調用callback(err)時,我的自定義異步回調被調用。在那裏我拋出了一個錯誤,希望它能夠在異步的try塊中被捕獲,但是這沒有發生。節點異步和異常處理

try { 
    async.waterfall([function1, function2], myAsyncCallback); 
} 
catch(err) { 
    console.log("THIS CODE IS NEVER EXECUTED."); 
} 

var function1 = function() { 
... 
    //some error occurs: 
    callback(new Error(errMsg), errMsg); 
... 
} 

var function2 = function() { 
... 
} 

function myAsyncCallback(err, result) { 
    console.log("This code gets executed."); 
    if (err) { 
      console.log("This code gets executed too."); 
      throw new Error("I want this error caught at the top around the catch around async.waterfall()"); 
     } 
} 
+0

這是代碼格式化的問題:現在你'聲明* myAsyncCallback'裏面你'function1'的*,所以這是不是真的懂事代碼。你可以減少這個[mcve],人們可以複製粘貼到文件並運行在節點上看到你看到的相同的東西,而不是發佈代碼,保證不會顯示你的問題,因爲它不能運行? –

+0

@Mike,他們實際上並不在彼此之內。更新了樣本,希望能夠說清楚。你應該能夠刪除「...」來測試它。 – user994165

+0

我添加了一個答案,但可能需要更深入瞭解所調用的函數。我發佈了我的工作代碼,這看起來很像你的例子! – clay

回答

1

https://runkit.com/imjosh/async-try-catch/2.0.0

var async = require('async'); 

try { 
    async.waterfall([function1, function2], myAsyncCallback); 
} 
catch(err) { 
    errorHandler(err); 
} 

function function1(callback) { 
    console.log('in fn1') 
    callback(null,'fn1'); 
} 

function function2(fn1, callback) { 
    console.log('in fn2') 
    callback(null, fn1 + 'fn2'); 
} 

function myAsyncCallback(err, result) { 
    if (err) { 
     console.error('There was an error: ' + err); 
     return; 
    } 
    //an error occurs. this gets caught by the outer try block 
    //var foo = outer; //oops, outer is not defined. This throws an error 

    //same scenario but inside an async function 
    //can't/won't be caught by the outer try block 
    setTimeout(function(){ 
     try{ //need try here 
      var foo = inner; //oops, inner is not defined. This throws an error 
     } 
     catch(err) { 
      errorHandler(err); 
     } 
    }, 1000); 

    console.log('Result was: ' + result); 
} 

function errorHandler(err){ 
    //Make error handler a function that can be called from either catch 
    console.log('caught error: ' + err); 
} 
+0

錯誤發生在異步模塊回調中,我稱之爲myAsyncCallback。函數1中的錯誤會被第一個try/catch塊捕獲,但這不是我想要做的。 – user994165

+0

我編輯了答案。所有的錯誤處理都在一個地方。處理myAsyncCallback中的異常。看到您的實際代碼時很難看到您想要做什麼。 – imjosh

0

適合我。你看到有什麼不同嗎?如果有更多的話,我會更新我的答案。

這是我的輸出:

[Clays-MacBook-Pro ~/Documents/workspace/scratch]:node index.js 
inside function1 
This code gets executed. 
This code gets executed too. 
THIS CODE IS NEVER EXECUTED. 
[Clays-MacBook-Pro ~/Documents/workspace/scratch]:node -v 
v6.9.1 
[Clays-MacBook-Pro ~/Documents/workspace/scratch]: 

此代碼:

var async = require('async') 
try { 
    async.waterfall([function1, function2], myAsyncCallback); 
} 
catch(err) { 
    console.log("THIS CODE IS NEVER EXECUTED."); 
} 

function function1(callback) { 
    console.log("inside function1"); 
    var errMsg = "Uh oh"; 
    callback(new Error(errMsg), errMsg); 
} 

function function2(stuff2, callback) { 
    console.log('inside function2'); 
    var errMsg = "Uh oh"; 
    callback(new Error(errMsg), errMsg); 
} 

function myAsyncCallback(err, result) { 
    console.log("This code gets executed."); 
    if (err) { 
      console.log("This code gets executed too."); 
      throw new Error("I want this error caught at the top around the catch around async.waterfall()"); 
     } 
    console.log(result); 
} 
+0

你的'function1'和'function2'正在同步調用它們的回調函數,這沒有任何意義。 'myAsyncCallback'應該是一個*異步*回調,否則'async.waterfall'首先不會被使用。 – Bergi

+0

Bergi,我相信我們應該在每個函數中調用回調函數(例如https://www.hacksparrow.com/node-js-async-programming.html)。讓我們將正常的異步處理變爲同步處理。也許我錯過了一些東西。 – user994165

+0

@Clay,你的樣品爲我工作。爲了測試我的代碼中的錯誤處理,我在回調中添加了throw語句,但我沒有創建錯誤並將其發送到回調:callback(err)。在我的代碼中,在上面的示例中,有一個if/else代替了「...」,導致回調調用不被執行。 – user994165

1

希望它會在周圍異步try塊被抓住,但沒有發生

這是不可能的。錯誤將被創建並異步拋出,即在async.waterfall已返回並且try塊被留下之後很久。如果您想處理異步錯誤,請在myAsyncCallback中執行(就像您已經這樣做)。在異步回調中從不使用throw

+0

這不是準確的。調用'async.waterfall'時創建的作用域將一直保留,直到連鎖死亡。拋出的錯誤會通過呼叫鏈「回升」。我同意拋出一個異步回調是有問題的(因爲跟蹤錯誤非常痛苦),但這不是不可能的。你能編輯這個答案嗎? – clay

+0

@clay你在說什麼範圍? OPs代碼中沒有關閉,因此範圍在離開時被破壞。或者,「直到鏈條死亡」是什麼意思?請注意,引發OP代碼的'myAsyncCallback'不會被'async.waterfall'調用 - 它是* asynchronous *。 – Bergi

+0

我想我是指回調鏈。但是你是正確的,如果回調是異步調用的,則會有不同的行爲。我猜想,我有一些學習要做!感謝您的回答。 – clay