[英]JavaScript async in a loop with callbacks
I have a tricky situation that needs to collect keys that belongs to certain types (types in a given array), then filter the collected keys and pass to a deletion function. 我有一个棘手的情况,需要收集属于某些类型(给定数组中的类型)的键,然后过滤收集的键并传递给删除函数。
The collection process calls shell codes and process the results in a callback within a loop. 收集过程调用外壳程序代码,并在循环内的回调中处理结果。 I will need to wait until the whole loop of callback finishes then pass to the deletion function. 我将需要等到整个回调循环完成,然后再传递给删除函数。
I am using shelljs in the node codes, basically look like the below: 我在节点代码中使用shelljs,基本上如下所示:
var del_arr = [];
for (var i in types) {
shell.exec(somecode with
var [i], {
silent: true
},
function(code, stdout, stderr) {
somecode-processing/filtering stdout and pushes the results to del_arr;
});
//loop through array types[] and need to wait for all shell codes' callbacks to finish;
}
//then pass del_arr to deletion function
I wasn't able to build a async function in this format b/s of the shelljs callback. 我无法使用shelljs回调的这种格式b / s构建异步函数。 I also don't know how to use promise in this situation. 我也不知道在这种情况下如何使用Promise。
Can you tell me how to achieve this non-blocking process? 您能告诉我如何实现这一非阻塞过程吗? Thanks 谢谢
Turn child_process.exec
into a promise: 将child_process.exec
变成一个承诺:
function execWrapper(command, options) {
return new Promise((resolve, reject) => {
shell.exec(command, options, (error, out, err) => {
if (error) return reject(error);
resolve({out: out, err: err});
})
})
}
Then you can iterate over types and map each one to a promise: 然后,您可以遍历类型并将每个类型映射到一个Promise:
const promises = types.map(type => execWrapper(type, {slient: true}));
Now wait for each promise to resolve, or for one to reject: 现在,等待每个诺言得以解决,或者一个诺言被拒绝:
Promise.all(promises).then((del_arr) => {
// del_arr is now a array of objects with the stdout and stderr of each type.
//
})
A good implementation of this case : 这种情况的良好实现:
async function myAsyncFunction() {
const promises = types.map((type) => myAsyncRequest(type));
let del_arr = Promise.all(promises);
}
A good article that explains this : 一篇很好的文章解释了这一点:
https://medium.freecodecamp.org/avoiding-the-async-await-hell-c77a0fb71c4c https://medium.freecodecamp.org/avoiding-the-async-await-hell-c77a0fb71c4c
Try to convert shell.exec to Promise like 尝试将shell.exec转换为Promise,例如
function shellPromise(command,option) {
return Promise((resolv,reject)=>{
shell.exec(command,option,(code,stdout,stderr)=>
resolv({code:code,stdout:stdout,stderr:stderr})
);
};
};
Then you can use something like 然后,您可以使用类似
for (var i in types){
var result=await shellPromise(somecode with var[i], {silent:true});
// somecode-processing/filtering stdout and pushes the results to del_arr;
}
You can also use async
package in npm. 您还可以在npm中使用async
包。 It provides a function eachSeries
that might come handy in your situation, without useing promises and dealing with callbacks only. 它提供了一个eachSeries
函数,在您的情况下可能会派上用场,而无需使用promises且仅处理回调。
async.eachSeries(hugeArray, function iteratee(item, callback) {
if (inCache(item)) {
callback(null, cache[item]); // if many items are cached, you'll overflow
} else {
doSomeIO(item, callback);
}
}, function done() {
//...
});
For more details on how to use this function: https://caolan.github.io/async/ 有关如何使用此功能的更多详细信息: https : //caolan.github.io/async/
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.