动态阵列的NodeJS async.each / parallel

时间:2018-07-25 06:28:33

标签: node.js async.js

a=['a','b','c'];//Dynamic array
async.each(a, function (item, callback){ 
console.log(item); // print the key

callback(); // This is final callback

}, function(err,res) {
    console.log('iterating done');
});

我要为数组a 的每个元素执行类似任务,并且我需要每个操作的结果,并且所有操作都是独立

请提出实现该目标的最佳方法

编辑#1

a是一个数组,其中包含需要执行的查询才能对Salesforce Org进行REST API调用。 对于每个查询,都发送了HTTP请求,我想独立保存所有响应。

注意::我不应该更改restcallmapperapi功能。

示例::a = ['从帐户中选择ID'];

async.each(a, (val,childcallback)=>{//WIP
    restcallmapperapi(val,childcallback);
        }, (err,result)=>{
            // i want result of each callback
            });



 var restcallmapperapi=(query,callback)=>{
    var headers={
        'Content-Type':'application/json',
        'Authorization':access_token
    };
    var newOptions={
        host:instance_url,
        port:null,
        path:squery+query,
        method:'GET',
        headers:headers
    };
    //console.log('query',instance_url,newOptions.path);
    var qryObj=https.request(newOptions,function(result){
        result.setEncoding('utf-8');
        var responseString1='';
        result.on('data',function(respObj){
            responseString1+=respObj;
        });
        result.on('end',function(){
            var resp=JSON.parse(responseString1);
            console.log('respo',resp.done,resp.totalSize,resp);
            if(resp.done && resp.totalSize>0){
                callback(null,resp);
            }
            else{
                callback('error for'+query);
            }

        });
    });
    qryObj.on('error',(e)=>{
        console.log('problemquery',e);
        callback('error in query object request '+e);
    });
    qryObj.end();
};

编辑#2

q = ['a','b','c'];

我需要数组每个元素的结果。但是,在下面的代码中,如果REST调用“ a”失败,则过程不会继续

  const rp = require('request-promise');

async function getData(array) {
    let results = [];
    var headers= {
        'Content-Type':'application/json',
        'Authorization':access_token
    };

    for (let item of array) {
        let newOptions={
            host:instance_url,
            port:null,
            path:squery+item,
            method:'GET',
            headers:headers
        };
        let data = await rp(newOptions);
        results.push(data);
    }
    return results;
}

let a = ['a','b','c'];  // Dynamic array

getData(a).then(allData => {
    // allData is array of results
    console.log(allData);
}).catch(err => {
    // process error here
    console.log(err);
})

;

2 个答案:

答案 0 :(得分:0)

使用async

var a=['a','b','c'];

async.map(a, function (elem, callback) {
  // for each product, update its DB entry
  console.log(elem);
  elem =elem + "H";
  callback(null, elem);
}, function (err, result) {
  // all finished
  console.log('database calls done', result);
});

使用“ Q”库:

var the_promises = []; //Maintain an Array.

arrList.forEach(function(elem){
  var deferred = Q.defer();
  DAO.create(elem, function(err, data){
    if(err){
       deferred.reject(err); // Reject if error.
    }else{
      deferred.resolve(data); // Resolve promises.
    }
    the_promises.push(deferred.promise); // Push promises to the array.
  });
});

Q.all(the_promises).then(function(values) { // When all promises done you will be here with all element output in the array.
  console.log(values[0]);
  console.log(values[1]);
}, function(err) {
  console.log(err);
});

答案 1 :(得分:0)

您可以像这样使用promise async/awaitrequest-promise库来依次运行您的请求,

const rp = require('request-promise');

async function getData(array) {
    let results = [];
    var headers= {
        'Content-Type':'application/json',
        'Authorization':access_token
    };

    for (let item of array) {
        let newOptions={
            host:instance_url,
            port:null,
            path:squery+item,
            method:'GET',
            headers:headers
        };

        let data = await rp(newOptions).catch(e => {
            console.log(e);
            // if error, make data be null and continue processing
            return null;
        });
        results.push(data);
    }
    return results;
}

let a = ['a','b','c'];  // Dynamic array

getData(a).then(allData => {
    // allData is array of results
    console.log(allData);
}).catch(err => {
    // process error here
    console.log(err);
});

或者,如果您的数组不太长,并且所请求的主机可以处理许多并行请求,则可以像这样并行运行请求,并可能得到更快的最终结果:

const rp = require('request-promise');

function getData(array) {
    var headers= {
        'Content-Type':'application/json',
        'Authorization':access_token
    };

    return Promise.all(array.map(item => {
        let newOptions={
            host:instance_url,
            port:null,
            path:squery+item,
            method:'GET',
            headers:headers
        };
        return rp(newOptions).catch(e => {
            // if error, put null into result array
            console.log(e);
            return null;
        });
    }));
}

let a = ['a','b','c'];  // Dynamic array

getData(a).then(allData => {
    // allData is array of results
    console.log(allData);
}).catch(err => {
    // process error here
    console.log(err);
})

以下是这段代码的背景:

  1. request-promise库是请求库的承诺版本。这意味着当整个请求完成后,它将返回一个承诺,使您可以使用承诺来控制异步控制流。承诺是用于管理异步操作的Javascript设计方向。
  2. 请求库是http.get()http.post()等的包装,为您提供了更高层次的接口。在这种情况下,我们最感兴趣的是让它为我们收集整个响应,而不是让我们编写代码来收集它。
  3. 在第一个选项中,async/await使我们可以编写非常简单的代码来序列化请求,以便在第一个请求完成之前不发送第二个请求。
  4. 在第二个选项中,我们并行运行所有请求,并让Promise.all()依次为我们收集所有结果,并告诉我们它们何时完成。