2013-06-27 4 views
0

Я создаю небольшое приложение, которому необходимо выполнить несколько HTTP-вызовов внешнему API и объединить результаты в один объект или массив. напримерПроблемы с обратным вызовом Nodejs

  1. Подключения к конечной точке и получить аутентификации ключа - передать аутентификации ключа к этапу

  2. Получить сводку доступных элементов элементов списка - Подключение к конечной точке с помощью ключа аутентификации и получить результаты JSON - создать объект, содержащий итоговые результаты и переходите к этапу 3.

  3. Итерация по итоговым итоговым результатам переданного объекта и вызов API для каждого элемента объекта для получения подробной информации для каждой сводной строки. Затем создайте единую структуру данных JSON, которая содержит сводную и подробную информацию.

Использование библиотеки nodejs асинхронного я могу получить как шаг 2, однако, поскольку шаг 3 включает в себя несколько запросов HTTP каждый со своими обратными вызовами, я заблудиться в обратном вызове ад.

Есть ли рекомендуемый способ легко справиться с этим типом использования с использованием узла?

ответ

1

Работа с несколькими обратными вызовами непростая. Однако там уже есть библиотеки, которые могут вам помочь, например Caolan's async.js. Решение может выглядеть так:

var async = require("async"); 

var myRequests = []; 

myArray.forEach(function(item) { 
    myRequests.push(function(callback) { 
     setTimeout(function() { 
      // this only emulates the actual call 
      callback(result); 
     }, 500); 
    }); 
}); 

async.parallel(myRequests, function(results) { 
    // this will fire when all requests finish whatever they are doing 
}); 
0

Простым решением будет подсчет вам обратные вызовы:

var results = []; 

function final_callback(results) 

function callback(result){ 
    results.push(result): 
    if (results.length == number of requests){ 
    final_callback(results); 
    } 
} 

Более приличное решение будет использование и EventEmitter событий со счетчиком:

my_eventEmitter.on('init_counter',function(counter){ 
    my_eventEmitter.counter=counter; 
}); 
my_eventEmitter.on('result',function(result){ 
    if(my_eventEmitter.counter == 0) return; 
    //stop all callbacks after counter is 0; 
    my_eventEmitter.results.push(result); 
    my_eventEmitter.counter--; 
    if(my_eventEmitter.counter == 0){ 
     my_eventEmitter.emit('final_callback'); 
    } 
}); 
my_eventEmitter.on('final_callback', function(){ 
    //handle my_eventEmitter.results here 
}) 

.... Теперь вам просто нужно сделать то же, но перед отправкой init_counter на событие эмиттера

my_eventEmitter.emit('init_counter',50); 
for(i=0; i<50; i++) async_function_call(some_params, function(result){ 
    my_eventEmitter.emit('result',result); 
});