2012-01-27 2 views
2

Есть ли элегантный способ асинхронного отображения объекта или массива в coffeescript? (. Или Javascript)асинхронная карта в coffeescript

Представьте У меня есть некоторые вещи в объекте:

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

thingCount = 3 

Я хочу, чтобы создать метод, который будет обрабатывать каждый из этих вещей и вернуть обработанный объект. Процесс должен сделать асинхронный вызов для получения некоторой информации о каждой вещи. Сначала я попытался просто перебрать свойства следующим образом:

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 

Проблема заключается в том, что значение ключевых изменений в цикле. Таким образом, мое решение, чтобы создать вложенную функцию так, что ключевой переменной содержится в его закрытия:

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 

Но мальчик здор`ово что уверен, Fugly. Есть ли предпочтительный шаблон для этого?

+1

использовать [утилиту карты] (https://github.com/Raynos/after.js/blob/master/src /after.js#L64) – Raynos

+0

«после» выглядит как хорошая библиотека Raynos - спасибо! – mainsocial

ответ

5

CoffeeScript покрывает это с do ключевого слова, описанным в конце Loops and Comprehensions:

При использовании цикла JavaScript для создания функции, это общая для вставки закрывающих оберток для того, чтобы гарантировать, что петли переменных закрытам и все сгенерированные функции не просто разделяют конечные значения. CoffeeScript предоставляет ключевое слово do, которое немедленно вызывает переданную функцию, пересылая любые аргументы.

for filename in list 
    do (filename) -> 
    fs.readFile filename, (err, contents) -> 
     compile filename, contents.toString() 

Он может быть применен к коду, как:

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 
+0

красивый, спасибо Джонатан! это скользкая часть javascript. – mainsocial

Смежные вопросы