coffeescript中的异步映射

mai*_*ial 2 javascript design-patterns node.js coffeescript

有没有一种优雅的方法来异步映射coffeescript中的对象或数组?(或者javascript.)

想象一下,我在对象中有一些东西:

things = 
  x: 
    ...
  y:
    ...
  z:
    ...

thingCount = 3
Run Code Online (Sandbox Code Playgroud)

我想创建一个方法来处理这些事情并返回处理过的对象.该过程必须进行异步调用以获取有关每个事物的一些信息.起初我试图像这样循环遍历属性:

processThings = (callback) ->

  processedThings = {}
  count = 0

  for key,val in things

    asyncJob key,val (err,result) ->

      if err
        callback error
      else
        # PROBLEM: key has the incorrect value here
        processedThings[key] = result      
        count += 1
        if count == thingCount
          callback null,processedThings
Run Code Online (Sandbox Code Playgroud)

问题是键的值在循环中发生了变化.所以我的解决方案是创建一个子函数,以便键变量包含在其闭包中:

processThings = (callback) ->

  processedThings = {}
  count = 0

  processThing = (key,val) ->

    asyncJob key,val (err,result) ->

      if err
        callback error
      else
        processedThings[key] = result      
        count += 1
        if count == thingCount
          callback null,processedThings

  processThing key,val for key,val of things
Run Code Online (Sandbox Code Playgroud)

但是,男孩,你确实很难受.这有一个首选模式吗?

Jon*_*ski 5

CoffeeScript使用在循环和理解do结尾处描述的关键字来涵盖此内容:

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

for filename in list
  do (filename) ->
    fs.readFile filename, (err, contents) ->
      compile filename, contents.toString()
Run Code Online (Sandbox Code Playgroud)

它可以应用于您的代码:

processThings = (callback) ->

  processedThings = {}
  count = 0

  for key,val in things

    # add this to close over `key`
    do (key) ->

      asyncJob key,val (err,result) ->

        if err
          callback error
        else
          processedThings[key] = result      
          count += 1
          if count == thingCount
            callback null,processedThings
Run Code Online (Sandbox Code Playgroud)