使用async.js在循环中执行异步操作

时间:2013-06-12 20:46:28

标签: javascript asynchronous coffeescript async.js

我知道我会发布这个然后让它发挥作用,更不用说标题了......

我需要为我给出的数组中的每个元素执行一些异步代码,然后在所有元素完成后进行一些检查。通常情况下,如果我在这里使用async.js,那么我做这件事的方式并不能得到我想要的结果。

所以这是我的逻辑,我想我可以创建一个函数数组,但是我这样做的方式似乎让async.js返回结果中的函数列表。

findLeadThatCanBeTaken : (leads, user, manualTake, cb) =>
  if(leads.length == 0) then return cb(null, null)

  funcArr = []
  self = this

  for lead in leads
    fun = (callback) ->
      console.log(lead.state)
      State.get lead.state, (e, state) ->
        if !state or state.canBeCalled(self.currentTime())
          return callback(null, lead._id.toString)

        return callback(null, null)

    funcArr.push(fun)

  async.parallel funcArr, (e, r) ->
    if (e)
      return cb(message:'No leads can be called at the current time', null)

    id = _.compact(r)
    id = r[0] if r.length

    if (!id || !id.length)
      return cb(message:'No leads can be called at the current time', null)

    lead = _.filter leads, (l) -> return l._id.toString() == id

    # Code handling 
    @takeLead(lead, user, cb)

我90%确定问题是这个我正在创建的阵列并没有像我想的那样被分配,但我不确定。谁知道我在这里做错了什么?

1 个答案:

答案 0 :(得分:2)

我猜你有一个经典的“闭环内部”问题:

for lead in leads
  fun = (callback) ->
    # some stuff that uses 'lead'...

问题是所有fun函数都会引用完全相同的lead,当这些函数执行时,lead将引用它在循环中的最后一个值

来自fine manual(该部分的底部):

  

当使用JavaScript循环生成函数时,通常会插入一个闭包装,以确保循环变量被关闭,并且所有生成的函数不只是共享最终值。 CoffeeScript提供do关键字,它立即调用传递的函数,转发任何参数。

听起来很熟悉?您可能希望在每次迭代时获得lead的值,而不是仅仅使用以下内容拖动lead

for lead in leads
  do (lead) ->
    fun = (callback) ->
      # What you have now...