【问题标题】:Using async.each with promises - async each never stops将 async.each 与 promise 一起使用 - async each 永远不会停止
【发布时间】:2016-10-21 04:44:22
【问题描述】:

我正在节点中构建这个函数,它混合了查询数据库和异步的承诺。 问题是 async.each 函数永远不会停止。 promise2 函数永远不会被触发。 这是我的代码中的问题还是不能将 async.each 函数与 Promise 混合? 有没有更好的方法来编写我想做的代码?

非常感谢您的帮助

promise1().then(function(arr1){
  async.each(arr1, function(obj1, callback) {
    build_select_request(obj1).then(function(select_request){
      query_database(select_request).then(function(result){
        if (result){                       
          build_update_request(obj1).then(function(update_request){                        
            do_query(update_request).then(function(result){                                          
              callback(null)
            }, function(error){
              callback(error)
            })
          }, function(error){
            callback(error)
          })
        } else {
          build_insert_request(obj1).then(function(insert_request){            
            do_query(insert_request).then(function(result){                                                                      
              callback(null)
            }, function(error){
              callback(error)
            })
          }, function(error){
            callback(error)
          })
        }
      }, function(error){
        callback(error)
      })
    }, function(error){
      callback(error)
    })
  }, function(err) {
    // if any of the file processing produced an error, err would equal that error
    if (err) {
      // One of the iterations produced an error.
      // All processing will now stop.
      reject(err)
    } else {
      promise2().then(function(success){        
        resolve(success)
      }, function(error){        
        reject(error)
      })
    }
  })
}, function(error){  
  reject(error)
})

【问题讨论】:

  • 如果你使用 Promise,你不需要 async,看看 bluebird.js bluebirdjs.com/docs/api/promise.each.html
  • 这看起来很糟糕。你违背了承诺的意义。
  • @JLRishe,你能帮我以更好的方式重写这段代码吗?我不明白 bluebird.js 上给出的示例我认为 promise.each 与我的情况无关。
  • 永远不要将 async 库与 promise 一起使用。

标签: javascript node.js asynchronous promise bluebird


【解决方案1】:

这是我的代码中的问题还是不能将 async.each 函数与 Promise 混合使用?

可以,但不应该。编写 Promise 代码,然后回退到回调,这就是你目前所拥有的。

相反,请确保使用正确的承诺链:

var promise = build_select_request(obj1).then(function(select_request){
  return query_database(select_request).then(function(result){
    if (result){                       
      return build_update_request(obj1).then(do_query);
      /* .then(function(update_request){                        
        return do_query(update_request);
      }) */
    } else {
      return build_insert_request(obj1).then(do_query);
      /* .then(function(insert_request){            
        do_query(insert_request)
      }) */
    }
  })
})

您现在可以像这样将它与async.each 一起使用:

async.each(arr1, function(obj1, callback) {
  var promise = …;
  promise.then(function(result) {      
    callback(null, result)
  }, function(error) {
    callback(error);
  });
}, function(err) {
  …
})

但您最好避免这种情况,而是使用Promise.all,这也可以让您避免您爱上的Promise constructor antipattern(鉴于您最外层回调中的resolve/reject 调用):

promise1().then(function(arr1) {
  return Promise.all(arr1.map(function(obj1) {
    var promise = …;
    return promise;
  }));
}).then(function(results) {
  …
}, function(err) {
  …
});

【讨论】:

    【解决方案2】:

    我错过了“返回”

    promise1().then(function(arr1){
      async.each(arr1, function(obj1, callback) {
        build_select_request(obj1).then(function(select_request){
          return query_database(select_request).then(function(result){
            if (result){                       
              return build_update_request(obj1).then(function(update_request){                        
                return do_query(update_request).then(function(result){                                          
                  callback(null)
                }, function(error){
                  callback(error)
                })
              }, function(error){
                callback(error)
              })
            } else {
              return build_insert_request(obj1).then(function(insert_request){            
                return do_query(insert_request).then(function(result){                                                                      
                  callback(null)
                }, function(error){
                  callback(error)
                })
              }, function(error){
                callback(error)
              })
            }
          }, function(error){
            callback(error)
          })
        }, function(error){
          callback(error)
        })
      }, function(err) {
        // if any of the file processing produced an error, err would equal that error
        if (err) {
          // One of the iterations produced an error.
          // All processing will now stop.
          reject(err)
        } else {
          promise2().then(function(success){        
            resolve(success)
          }, function(error){        
            reject(error)
          })
        }
      })
    }, function(error){  
      reject(error)
    })
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-01-14
      • 1970-01-01
      • 2013-06-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多