Как сделать несколько асинхронных вызовов, а затем выполнить функцию после завершения всех вызовов? - PullRequest
0 голосов
/ 31 августа 2018

У меня есть веб-сервер nodeJS, который вызывает другой API для получения данных, а затем (в идеале) возвращает эти данные на веб-страницу. Я использую библиотеку запроса-обещания и пытаюсь использовать Promise.all () безрезультатно.

Что у меня так далеко:

app.get('/endpoint', (req, res) => {
  var url = 'some url';
  var dataObject = {};
  var promise1 = rp(url).then( (data) => {
    //process data into dataObject
  }
  url = 'another url';
  var promise2 = rp(url).then( (data) => {
    //process data into dataObject
  }
  //same thing for promise 3...
  Promise.all([promise1, promise2, promise3]).then(res.send(dataObject));
});

Проблема в том, что res.send(dataObject) не ждет окончания выполнения обещаний, поэтому отправляет пустой объект. Я не очень знаком с обещаниями и пытаюсь узнать о них больше, но дела идут не так, как я ожидал. Если бы я догадался о том, что происходит, при вызове rp().then(), .then() вызывает обещание разрешиться, а затем он выполняет код внутри .then() после «разрешения».

Я хочу, чтобы выполнялся код внутри .then(), а затем, когда все обещания закончили обработку своих индивидуальных данных, я хочу, чтобы он выполнил .all().then(), чтобы вернуть эти данные, но как мне поступить?

Ответы [ 2 ]

0 голосов
/ 31 августа 2018

Дополнительное примечание: вы можете использовать async / await, как показано ниже, что адаптация такого решения могла бы предотвратить вашу ошибку, как уже указывал другой ответ.

app.get('/endpoint', async (req, res) => {
  var url = 'some url';
  var dataObject = {};
  var promise1 = rp(url).then( (data) => {
    //process data into dataObject
  });
  url = 'another url';
  var promise2 = rp(url).then( (data) => {
    //process data into dataObject
  });
  //same thing for promise 3...

  let dataObject = await Promise.all([promise1, promise2, promise3]);
  res.send(dataObject);
});
0 голосов
/ 31 августа 2018

.then() необходимо передать ссылку на функцию. Вы не проходите это так. Изменить это:

Promise.all([promise1, promise2, promise3]).then(res.send(dataObject));

к этому:

Promise.all([promise1, promise2, promise3]).then(data => res.send(dataObject));

Ваша версия кода немедленно выполняет res.send(dataObject), а затем передает возвращаемое значение из этого значения в .then(). Вы должны передать ссылку на функцию в .then(), чтобы инфраструктура обещания могла вызвать эту функцию через некоторое время.


Чтобы проиллюстрировать, ваша версия кода работает примерно так:

let f = res.send(dataObject);
Promise.all([promise1, promise2, promise3]).then(f);

Как вы можете ясно видеть, вы выполняете res.send() ДО Promise.all().then() может сделать это.

Вместо этого вы хотите сделать что-то вроде этого:

function f() {
    res.send(dataObject);
}
Promise.all([promise1, promise2, promise3]).then(f);

Где вы явно передаете функцию, которую позже можно вызвать, на .then(). Сокращенная версия этого:

Promise.all([promise1, promise2, promise3]).then(data => res.send(dataObject));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...