Не удается получить сценарий замороженного кофе с такими пониманиями, как карта или уменьшение

В общем, сегодня я обнаружил iced-coffee-script и был очень рад увидеть, что кто-то попытался разработать более читаемый диалект coffee-script для асинхронного программирования.

Я не могу заставить себя работать с такими понятиями, как карты и функции сокращения, или, проще говоря, делать/для. Например. вывод из...

square = (x, callback) ->
  setTimeout ->
      callback x * x
    , 5000

console.log [ 1..10 ].map (x) ->
  await square x, defer y
  y  

... это просто массив неопределенных значений! Что мне не хватает? Заранее спасибо.

Джачекко


person giacecco    schedule 14.12.2012    source источник


Ответы (2)


Я новичок в замороженном виде, но вот мое понимание:

Использование await и defer на самом деле не останавливает поток управления, ваша функция вернется как обычно. Таким образом, для каждого элемента .map возвращается значение «undefined».

Вот серийная версия, как указано выше:

foo = []
for x in [ 1..10 ]
  await square x, defer y
  foo.push y

Если вы хотите сделать это параллельно, это так:

foo = []
await
  for x,i in ([ 1..10 ])
    square x, defer foo[i]

Обратите внимание, что я заключаю диапазон [1..10] в круглые скобки. Это делается для того, чтобы диапазон расширялся до массива, чтобы мы могли получить индекс внутри цикла, как описано здесь: https://github.com/jashkenas/coffee-script/issues/2586

.push здесь не сработает, потому что обратные вызовы, как правило, не гарантируются в том порядке, в котором вы хотите.

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

person doubledriscoll    schedule 17.12.2012

Я добавлю свои 2 цента к ответу @doubledriscoll, чтобы вы могли лучше понять, что здесь происходит на самом деле. Давайте просто переведем ваш пример кода в обычный javascript, поэтому этот код:

console.log [ 1..10 ].map (x) ->
  await square x, defer y
  y  

Является эквивалентом:

console.log([1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map(function(x) {
  return square(x, function(y) {
    return y;
  });
});

Который напечатает массив вещей, возвращаемых функцией square, то есть undefined.

person Andrew    schedule 15.01.2013