質問

Consider this snippet of code :

function foo(a) {
  console.log("Mul =", a);
  return a * 2;
};

function * process(start) {
  // next() #1
  var result = start;

  console.log("Pre-processing =", result);
  result = yield foo(result);
  // next() #2
  console.log("Process result 1 =", result);
  result = yield foo(result);
  // next() #3
  console.log("Process result 2 =", result);
  result = yield foo(result);
  // next() #4
  console.log("Process result 3 =", result);

  return foo(result);
}

var it = process(1);
console.log("#1");
console.log("Next 1 =", /*#1*/it.next("bar"));
console.log("#2");
console.log("Next 2 =", /*#2*/it.next(3));
console.log("#3");
console.log("Next 3 =", /*#3*/it.next(7));
console.log("#4");
console.log("Next 4 =", /*#4*/it.next(15));

And the output

#1
Pre-processing = 1
Mul = 1
Next 1 = { value: 2, done: false }
#2
Process result 1 = 3
Mul = 3
Next 2 = { value: 6, done: false }
#3
Process result 2 = 7
Mul = 7
Next 3 = { value: 14, done: false }
#4
Process result 3 = 15
Mul = 15
Next 4 = { value: 30, done: true }

Why is the first call to it.next() skip arguments (in the code above, "bar") altogether? Or, in other words, why is the behavior different in subsequent calls? I would've expected calling the generator function would skip arguments, and that the call to next() would actually initialize the iterator, making the process more coherent, no?

役に立ちましたか?

解決

In the draft:

After some more research, the answer lies within harmony's draft (see the wiki: http://wiki.ecmascript.org/doku.php?id=harmony:generators#methodnext).

next is supposed to have no argument. However, it seems calling next with one argument is just equivalent to call send with one argument. Here lies the answer. send is designed to throw an error if called first (no next prior).

So basically, you should not be able to "initialize" your iterator by passing an argument to next cause you're not authorized to do so.

In the implementations:

However, this is just the specification. To summarize what's been said as comments, there are at least 2 reasons why you can't pass an argument to your first next and have to pass it to your generator.

The first one would be the fact that you would need some method to actually get this argument. You cannot do it the same way you'd do it with your next calls let myVar = yield myValue.
The second one would be that next only accepts one argument and that is quite limiting, whereas you can pass an infinite amount of arguments to your generator when producing the iterator.

However, this is only what's happening at the moment. Nothing says that the draft or implementations won't change. We could certainly imagine send accepting any number of arguments (no reason but hey, who knows), and being able to cast it into the generator's arguments. Or whatever.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top