ES6 yield : what happens to the arguments of the first call next()?

强颜欢笑 提交于 2019-12-08 12:45:07

问题


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?


回答1:


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.



来源:https://stackoverflow.com/questions/20977379/es6-yield-what-happens-to-the-arguments-of-the-first-call-next

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!