如何运行多个异步函数然后执行回调

Coo*_*oop 28 javascript api node.js

在我的NodeJS代码中,我需要进行2或3次API调用,每次调用都会返回一些数据.完成所有API调用后,我想将所有数据收集到一个JSON对象中以发送到前端.

我知道如何使用API​​回调(下一次调用将在前一次调用的回调中发生),但这会很慢:

//1st request
request('http://www.example.com', function (err1, res1, body) {

  //2nd request
  request('http://www.example2.com', function (err2, res2, body2) {

    //combine data and do something with it

  });

});
Run Code Online (Sandbox Code Playgroud)

我知道你也可以做类似的事情并且更符合承诺,但我认为同样的概念适用于下一个调用在当前调用完成之前不会执行的情况.

有没有办法同时调用所有函数,但是我的最后一段代码是等待所有API调用完成并在执行之前提供数据?

Mad*_*iha 48

承诺给你Promise.all()(这对本地承诺以及像蓝鸟这样的图书馆都是如此).

更新:自Node 8以来,您可以util.promisify()像使用Bluebird一样使用.promisify()

var requestAsync = util.promisify(request); // const util = require('util')
var urls = ['url1', 'url2'];
Promise.all(urls.map(requestAsync)).then(allData => {
    // All data available here in the order of the elements in the array
});
Run Code Online (Sandbox Code Playgroud)

那么你可以做什么(本机):

function requestAsync(url) {
    return new Promise(function(resolve, reject) {
        request(url, function(err, res, body) {
            if (err) { return reject(err); }
            return resolve([res, body]);
        });
    });
}
Promise.all([requestAsync('url1'), requestAsync('url2')])
    .then(function(allData) {
        // All data available here in the order it was called.
    });
Run Code Online (Sandbox Code Playgroud)

如果你有蓝鸟,这甚至更简单:

var requestAsync = Promise.promisify(request);
var urls = ['url1', 'url2'];
Promise.all(urls.map(requestAsync)).then(allData => {
    // All data available here in the order of the elements in the array
});
Run Code Online (Sandbox Code Playgroud)


Ben*_*Ben 12

听起来像async.parallel()如果您想使用async,它也可以完成这项工作:

var async = require('async');

async.parallel({
    one: function(parallelCb) {
        request('http://www.example1.com', function (err, res, body) {
            parallelCb(null, {err: err, res: res, body: body});
        });
    },
    two: function(parallelCb) {
        request('http://www.example2.com', function (err, res, body) {
            parallelCb(null, {err: err, res: res, body: body});
        });
    },
    three: function(parallelCb) {
        request('http://www.example3.com', function (err, res, body) {
            parallelCb(null, {err: err, res: res, body: body});
        });
    }
}, function(err, results) {
    // results will have the results of all 3
    console.log(results.one);
    console.log(results.two);
    console.log(results.three);
});
Run Code Online (Sandbox Code Playgroud)

  • 我弄清楚了我需要什么。我说的是 async.map(handleList, findStatus, function(err, results) { ... }); 其中 findStatus 是函数,该函数将被调用次数与 handleList 中存在的项目数相同。 (2认同)