关于async parallel的问题
发布于 9 年前 作者 asfman 4449 次浏览 最后一次编辑是 8 年前 来自 问答

现在我有一个数组,包含一组id, 然后用mongoose去查询更新数据 var ids = [1,2,3,4,5]; var successLen = 0; ids.forEach(function(id) { merchandiseModel.findByIdAndUpdate(id, { $inc: { order_num: 2 } }, function(err, numberAffected, rawResponse) {

	if(err){
		console.error(err.message);
        return;				
	}
	if(numberAffected == 1)
 		successLen++;
});

} 用async如何去获取最后更新的成功数successLen?

7 回复
async.inject(ids, 0, function (successLen, id, callback) {
  Model.findByIdAndUpdate(id, update, function (err, Model) {
    if (err) return callback(err)
    callback(null, ++successLen)
  })
},

function (err, successLen) {
  if (err) return // handle err...
  console.log('successLen', successLen)
})

這樣寫會不會更簡單些:

Model.update(conditions, update, { multi: true }, function (err, numberAffected) {
  if (err) return // handle err...
  console.log('numberAffected', numberAffected)
})

參考討論看看。 :)

多谢,不过,你上面的有点问题,如果if(err)满足条件 callback(err),这样会导致立马执行最后一个函数,接下来的id不会再执行了. Model.update的话,如果是一个很大的数组,然后update的值是各不相同的,这个怎么写?比如数据: data = [{id: 1, num: 123}, {id:2, num: 321}…] 现在根据data数组的id去查找数据,找到后更新num,如何根据data写conditions,update?

如果不要 break loop 那就是用 async.each 了:

var successLen = 0

async.each(ids, function (id, callback) {
  Model.findByIdAndUpdate(id, update, function (err, numberAffected) {
    if (err) return callback(err)
    if (numberAffected === 1) successLen++
    callback(null)
  })
},

function (err) {
  if (err) return // handle err
  console.log('successLen', successLen)
})

丟一個 successLen 在外部我覺得這樣寫好醜,不曉得有沒有更漂亮的寫法。

Model.update 依不同 id 寫入不同 data 應該沒有辦法用一條簡單的條件句,可能一定得要用 loop 完成。

async好像只要调用callback(err)就会立刻中断, 最后我还是用你的async.inject处理的,不调用callback(err)就好 if(err) callback(null, successLen)

@asfman

async.each 碰到 callback(err) 不會中斷吧?

async.each 最後的 callback 有兩種情況會被觸發:

  • 當錯誤發生時,也就是 callback(err) 有傳入值進去
  • 所有 iterator 完成時

值得注意的是,當發生 err 時第二個情況不會執行。示意:

async.each([1, 2, 3], function (item, done) {
  console.log('item', item)
  if (item === 2) return done(item)
  done(null)
},

function (err) {
  if (err) return console.log('err', err)
  console.log('done')
})

// item 1
// item 2
// err 2
// item 3
async.each([1, 2, 3], function (item, done) {
  console.log('item', item)
  done(null)
},

function (err) {
  if (err) return console.log('err', err)
  console.log('done')
})

// item 1
// item 2
// item 3
// done

@chinghanho each果然会都执行一遍,我看到文档里的 >the main callback (for the each function) is immediately called with the error. 以为执行了main callback就表示结束了…,不过要统计成功的数目,还是用inject优雅点

@chinghanho 赞答案 @asfman 确实用 inject 更符合函数式编程的思想。但代码上来说的话,.each 应该优雅点吧?多个 count 变量而已。

回到顶部