2015-12-24 4 views
0

Я пытаюсь запустить именованную функцию, которая использует async.waterfall(), в рамках другой функции, использующей async.waterfall().Node.js Обратные вызовы в вложенных функциях Async.Waterfall()

Как структурировать обратные вызовы, чтобы выход внутренней функции передавался внешней функции?

Следующий код не использует вложенные асинхронные-х и работает отлично:

//nested_async_1.js 

var async = require("async"); 

console.log("Script running"); 

// Inner function, to be called by the outer function 
var InnerAsync = function(callback_inner_async) { 

    async.waterfall([ 
     function (callback) { 
      console.log("Inner function 1"); 
      callback(null, "results 1") 
     }, 

     function (input_1, callback){ 
      console.log("function 2 " + input_1); 
      callback(null, "results 2") 
     } 
    ], 
    function (err, final_result) { 
     if (err) { 
      console.log("Server error: ", err); 
      callback(err) 
     } 
     else{ 
      var return_val = "Final result " + final_result; 
      console.log(return_val); 
      callback_inner_async(return_val); 
     } 
    }); 
}; 


// Outer function 
InnerAsync(function(result){ 
    console.log("Outer function " + result); 
}); 

Выход

C:\Data\>node nested_async_1.js 
Script running 
Inner function 1 
function 2 results 1 
Final result results 2 
Outer function Final result results 2 

В то время как следующий вложенный код асинхронный не работает:

//nested_async_2.js 

var async = require("async"); 

console.log("Script running"); 

// Inner function, to be called by the outer function 
var InnerAsync = function(callback_inner_async) { 

    async.waterfall([ 
     function (callback) { 
      console.log("Inner function 1"); 
      callback(null, "results 1") 
     }, 

     function (input_1, callback){ 
      console.log("function 2 " + input_1); 
      callback(null, "results 2") 
     } 
    ], 
    function (err, final_result) { 
     if (err) { 
      console.log("Server error: ", err); 
      callback(err) 
     } 
     else{ 
      var return_val = "Final result " + final_result; 
      console.log(return_val); 
      callback_inner_async(return_val); 
     } 
    }); 
}; 

// Outer function, which calls the inner function 
async.waterfall([ 
    function(callback_outer){ 
     console.log("Outer function 1"); 
     callback_outer(null, "Outer result 1") 
    }, 
    function(input_1, callback_outer){ 
     console.log("Outer function 2"); 
     // Run the inner function, and get the results 
     // How should this be structured??? 
     callback_outer(null, InnerAsync()) 
    } 
], 
    function(err, final_outer_result){ 
     if(err){ 
      console.log("Error on outer function: " + err) 
     } 
     else { 
      console.log("Final outer function"); 
      console.log(final_outer_result); 
     } 
    } 
); 

Выход

C: \ Data> узел nested_async_2.js
Скрипт работает
внешняя функция 1
Внешняя функция 2
Внутренняя функция 1
функции 2 Результаты 1
Final внешняя функция
неопределенными
Итоговые результат результата 2
C: \ Data \ nested_async_2.js: 31
callback_inner_async (return_val);
^

TypeError: callback_inner_async не является функцией
в C: \ Data \ nested_async_2.js: 31: 13
в C: \ Data \ node_modules \ асинхронной \ Lib \ async.js: 52: 16
в Immediate._onImmediate (C: \ Data \ node_modules \ асинхронной \ Lib \ async.js: 1201: 34)
в processImmediate [в _immediateCallback] (timers.js: 374: 17)

ответ

1

Вместо

function(input_1, callback_outer){ 
    console.log("Outer function 2"); 
    // Run the inner function, and get the results 
    // How should this be structured??? 
    callback_outer(null, InnerAsync()) 
} 

должно быть

function(input_1, callback_outer){ 
    console.log("Outer function 2"); 
    InnerAsync(function(result) { 
     console.log("Result from InnerAsync: ", result); 
     callback_outer(null, result); 
    }); 
} 

работать, как ожидалось. В вашем nested_async_2.js вы вызываете InnerAsync без обратного вызова, поэтому он не работает при попытке вызвать его.

Также есть несколько проблем с обработкой ошибок в InnerAsync.Эта функция не следует error-first callback шаблона и как взаимосвязанное вещь, код потерпит неудачу на этих линиях

function (err, final_result) { 
    if (err) { 
     console.log("Server error: ", err); 
     callback(err) // will fail here 
    } 

(если произошла ошибка), потому что callback не определена там.

+0

Работает отлично - Спасибо @svlapin –

0

Я думаю, что вы звонят InnerAsync без каких-либо аргументов; , поэтому при вызове InnerAsync вы не передаете функцию обратного вызова callback_inner_async, что вы получаете ошибку.

попробовать это:

async.waterfall([ 
    function(callback_outer){ 
     console.log("Outer function 1"); 
     callback_outer(null, "Outer result 1") 
    }, 
    function(input_1, callback_outer){ 
     console.log("Outer function 2"); 

     // Call InnerAsync with the callback function 

     InnerAsync(callback_outer); 
    } 
], 
    function(err, final_outer_result){ 
     if(err){ 
      console.log("Error on outer function: " + err) 
     } 
     else { 
      console.log("Final outer function"); 
      console.log(final_outer_result); 
     } 
    } 
); 
+0

Не работает, так как 'InnerAsync' вызывает свой обратный вызов, передавая результат успешного выполнения в качестве первого параметра, в то время как' async' ожидает получить объект ошибки. Таким образом, это будет рассматриваться как неудачная цепочка «водопад». –

Смежные вопросы