使用asise.each和promises - async,每个都不会停止

时间:2016-10-21 04:44:22

标签: javascript node.js asynchronous promise bluebird

我在节点中构建此函数,该节点是查询DB和异步的promises的混合。 问题是async.each函数永远不会停止。 promise2函数永远不会被触发。 这是我的代码中的问题还是不能将async.each函数与promises混合使用? 有没有更好的方法来编码我想要做的事情?

非常感谢你的帮助

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

2 个答案:

答案 0 :(得分:2)

  

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

可以,但不应该。编写承诺代码然后回退到回调会导致你现在拥有的东西。

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

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

答案 1 :(得分:0)

我错过了“回归”

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