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


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组织的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);
})

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

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

最新更新