如何进行多个异步调用,然后在所有调用完成后执行一个函数?

时间:2018-08-31 17:17:11

标签: javascript asynchronous promise

我有一个nodeJS Web服务器,该服务器调用另一个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()中的代码,然后一旦所有的Promise完成了各自的数据处理,我希望它执行.all().then()以返回该数据,但是我该怎么办?关于这样做吗?

2 个答案:

答案 0 :(得分:4)

.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(),以便Promise基础结构可以在以后再调用该函数。


为说明起见,您的代码版本与此类似:

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));

答案 1 :(得分:0)

旁注:您可以像下面那样使用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);
});