2015-04-04 2 views
1

Учитывая ситуацию, когда вам нужно получить данные из нескольких асинхронных функций или обещаний, что является лучшим способом сбора и сохранения данных, чтобы они могли быть использованы после завершения. Примером может быть несколько запросов к базе данных, которые необходимо отображать на одной странице.сбор данных из нескольких асинхронных функций (обещаний)

Я столкнулся с приведенным ниже кодом, который выглядит как сплошной шаблон для меня, но, будучи новичком в асинхронной игре, не уверен.

function complexQuery(objectId) { 
    var results = {}; 
    return firstQuery.get(objectId).then(function (result1) { 
      results.result1 = result1; 
      return secondQuery.find(); 
     }) 
     .then(function (result2) { 
      results.result2 = result2; 
      return thirdQuery.find(); 
     }) 
     .then(function (result3) { 
      results.result3 = result3; 
      return results; 
     }); 
} 

complexQuery(objectId) 
    .then(function (results) { 
     //can use results.result1, results.result2, results.result3 
     res.render('dash', results); //example use 
    }); 

Каков наилучший способ справиться с такой ситуацией?

Редактировать для уточнения: Должно быть последовательно, запросы могут потребовать информацию из предыдущего результата обещания.

+0

Если запросы должны быть последовательно, ваш код должен отражать это. – Bergi

+0

Есть ли что-нибудь, на что не ответил [канонический дубликат] (http://stackoverflow.com/q/28250680/1048572)? Я склонен к закрытию, но не стесняйтесь редактировать и задавать более конкретный вопрос - возможно, с вашим реальным кодом. – Bergi

ответ

0

Лучший способ сохранить все свои обещания в массив и использовать Q.all() или асинхронной эквивалент, который я думаю, что это то же самое, чтобы запустить функцию после того, как все завершено

+0

, который будет работать только в том случае, если обещания не требуют информации друг от друга. – Ryhnn

+0

Вы используете async. Вы можете использовать async.series для последовательного запуска последовательно, чтобы вы могли использовать информацию из предыдущего, которая похожа на то, что у вас уже есть – Ardenexal

2

Самый простой способ заключается в использовании Promise.all, который имеет преимущество делать запросы параллельно:

function complexQuery(objectId) { 
    return Promise.all([firstQuery.get(objectId), 
         secondQuery.find(), 
         thirdQuery.find()]) 
    .then(([result1, result2, result3] => {result1, result2, result3}); // ES6 syntax 
    /* ES5 equivalent would be 
    .then(function(results) { 
     return {result1: results[0], result2: results[1], result3: results[2]}; 
    }); */ 
} 

Если вам необходимо выполнить запросы в последовательности (потому что они зависят друг от друга), посмотреть на How do I access previous promise results in a .then() chain?, где различные стратегии (такие как один из приведенных в вашем вопросе, который imo is not a good one) подробно объяснены.

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