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

JWA*_*pin 3 javascript asynchronous promise

我有一个 nodeJS Web 服务器,它调用另一个 api 来获取数据,然后(理想情况下)将该数据返回到网页。我正在使用 request-promise 库并尝试使用 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));
});
Run Code Online (Sandbox Code Playgroud)

问题是它res.send(dataObject)没有等待承诺完成,所以它发送了一个空对象。我对 Promise 不是很熟悉,我试图通过这个来了解更多关于它们的信息,但事情并没有像我期望的那样做。如果我猜测发生了什么,当调用rp().then(),.then()导致承诺解决,然后.then()在“解决”后执行里面的代码。

我想要的是里面的代码.then()来执行,然后一旦所有的承诺都完成了他们各自的数据处理,我希望它执行.all().then()返回该数据,但我将如何去做呢?

jfr*_*d00 5

.then()需要传递一个函数引用。你没有通过它。改变这个:

Promise.all([promise1, promise2, promise3]).then(res.send(dataObject));
Run Code Online (Sandbox Code Playgroud)

对此:

Promise.all([promise1, promise2, promise3]).then(data => res.send(dataObject));
Run Code Online (Sandbox Code Playgroud)

您的代码版本会res.send(dataObject)立即执行,然后将返回值从该版本传递给.then(). 您必须向 传递一个函数引用,.then()以便承诺基础设施可以在一段时间后调用该函数。


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

let f = res.send(dataObject);
Promise.all([promise1, promise2, promise3]).then(f);
Run Code Online (Sandbox Code Playgroud)

正如您可以清楚地看到的那样,您正在执行res.send()BEFOREPromise.all().then()可以做的事情。

相反,你想要做这样的事情:

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

您清楚地将稍后可以调用的函数传递给.then(). 这个的缩短版本是:

Promise.all([promise1, promise2, promise3]).then(data => res.send(dataObject));
Run Code Online (Sandbox Code Playgroud)