【问题标题】:JavaScript async in a loop with callbacks带有回调的循环中的 JavaScript 异步
【发布时间】:2018-12-10 06:25:03
【问题描述】:

我有一个棘手的情况,需要收集属于某些类型(给定数组中的类型)的键,然后过滤收集到的键并传递给删除函数。

收集过程调用外壳代码并在循环内的回调中处理结果。我需要等到整个回调循环完成后再传递给删除函数。

我在节点代码中使用了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

我无法以这种 shelljs 回调的 b/s 格式构建异步函数。我也不知道在这种情况下如何使用promise。

你能告诉我如何实现这个非阻塞进程吗? 谢谢

【问题讨论】:

    标签: javascript node.js asynchronous ecmascript-6 es6-promise


    【解决方案1】:

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

    然后您可以迭代类型并将每个类型映射到一个承诺:

    const promises = types.map(type => execWrapper(type, {slient: true}));
    

    现在等待每个 Promise 解决,或者等待一个 Promise 被拒绝:

    Promise.all(promises).then((del_arr) => {
      // del_arr is now a array of objects with the stdout and stderr of each type.
      // 
    })
    

    【讨论】:

      【解决方案2】:

      这个案例的一个很好的实现:

      async function myAsyncFunction() {
        const promises = types.map((type) => myAsyncRequest(type));
        let del_arr = Promise.all(promises);
      }
      

      一篇很好的文章解释了这一点:

      https://medium.freecodecamp.org/avoiding-the-async-await-hell-c77a0fb71c4c

      【讨论】:

        【解决方案3】:

        尝试将 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})
              );
           };
        };
        

        然后你可以使用类似的东西

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

        【讨论】:

          【解决方案4】:

          你也可以在 npm 中使用async 包。它提供了一个函数eachSeries,在您的情况下可能会派上用场,而无需使用承诺并仅处理回调。

          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() {
              //...
          });
          

          有关如何使用此功能的更多详细信息:https://caolan.github.io/async/

          【讨论】:

            猜你喜欢
            • 2015-04-18
            • 2019-02-15
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-08-11
            • 1970-01-01
            • 2018-03-09
            相关资源
            最近更新 更多