NodeJS async.each/parallel 用于动态数组

NodeJS async.each/parallel for dynamic array

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 是一个数组,其中包含需要为 REST API Salesforce Org 调用执行的查询。 对于每个查询都有一个 HTTP 请求发送,我想保存所有响应独立

注意:我不应该更改 restcallmapperapi 函数。

例如: a=['Select Id from Account'];

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'];

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

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

;

使用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);
});

您可以像这样使用 promises、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 库是请求库的承诺版本。这意味着当整个请求完成时它 returns 一个承诺允许您使用承诺来控制您的异步控制流。承诺是管理异步操作的 Javascript 设计方向。
  2. 请求库是 http.get()http.post() 等的包装器...为您提供更高级别的接口。在这种情况下,我们最感兴趣的是让它为我们收集整个响应,而不是让我们编写代码来收集它。
  3. 在第一个选项中,async/await 允许我们编写非常简单的代码来序列化请求,以便在第一个完成后才发送第二个。
  4. 在第二个选项中,我们运行并行处理所有请求,让Promise.all()按顺序为我们收集所有结果,并在完成时告诉我们。