0

結局のところ、私は今日 iced-coffee-script を発見し、誰かが非同期プログラミング用のより読みやすい coffee-script 方言を設計しようとしたのを見てとてもうれしく思いました。

map 関数や reduce 関数、またはより単純な do/for などの理解を使用しても、作業に集中できません。例えば...の出力

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

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

... は単に未定義の配列です! 私は何が欠けていますか?前もって感謝します。

ジャセッコ

4

2 に答える 2

1

私はアイスに不慣れですが、ここに私の理解があります:

await and deferを使用しても、実際には制御フローが停止することはなく、関数は通常どおりに戻ります。そのため、.mapは要素ごとに「未定義」を返します。

上記のシリアルバージョンは次のとおりです。

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はここでは機能しません。これは、コールバックが通常、希望する順序で返されることが保証されていないためです。

これを行うには他にもたくさんの方法がありますが、これが上記でやろうとしていることを行うための最も簡潔な方法だと思います。大きなループの場合は、最初にその配列全体が割り当てられるため、非効率的である可能性があることに注意してください。

于 2012-12-17T00:17:02.617 に答える
0

ここで実際に何が起こっているのかをよりよく理解できるように、@doubledriscoll の回答に 2 セントを追加します。コード例を通常の 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

于 2013-01-15T06:32:26.280 に答える