I am using node 4.1.1. When I run this code
我使用的是节点4.1.1。当我运行这个代码。
"use strict";
function *generator() {
let numbers = [1,2,3,4,5];
numbers.map(n => yield (n + 1));
}
for (var n of generator()) {
console.log(n);
}
I get this error
我得到这个错误
numbers.map(n => yield (n + 1));
^^^^^
SyntaxError: Unexpected strict mode reserved word
If I rearrange the code to be this
如果我把代码重新排列成这样
"use strict";
function *generator() {
let numbers = [1,2,3,4,5];
let higherNumbers = numbers.map(n => n + 1);
for(let i=0;i<higherNumbers.length;i++) {
yield higherNumbers[i];
}
}
for (var n of generator()) {
console.log(n);
}
I get the expected result.
我得到了预期的结果。
Why does the second one work, and the first fail? And surely if a keyword is reserved, it's reserved in all contexts, not just when it's used in a arrow function?
为什么第二个有效,第一个失败?如果关键字是保留的,它在所有上下文中都保留,而不只是在箭头函数中使用?
5 个解决方案
#1
7
It is because arrow functions are not generator functions. For example,
这是因为箭头函数不是生成器函数。例如,
function temp() {
yield 1;
}
Can we expect this to work? No. Because temp
is not a generator function. The same is applicable to arrow functions as well.
我们能指望它起作用吗?不。因为temp不是生成器函数。同样也适用于箭头函数。
FWIW, the usage of yield
in an Arrow function is an early error as per the ECMAScript 2015 specification, as per this section,
FWIW,在箭头函数中使用yield是根据ECMAScript 2015规范的早期错误,根据本节,
ArrowFunction : ArrowParameters => ConciseBody
ArrowFunction: ArrowParameters => ConciseBody。
It is a Syntax Error if ArrowParameters Contains YieldExpression is true.
如果ArrowParameters包含屈服表达式,那么它就是一个语法错误。
It is a Syntax Error if ConciseBody Contains YieldExpression is true.
如果ConciseBody包含YieldExpression,则是语法错误。
#2
11
You can do anything but not everything – Learn to delegate
你可以做任何事,但不能做任何事——学会委派
Let's first look at two examples
让我们先看两个例子
1. yield
1。收益率
function* generator(numbers) {
yield numbers.map(x => x + 1);
}
for (let n of generator([1,2,3])) console.log(n);
// [ 2, 3, 4 ]
Our for
loop logs each value yielded by the generator. Inside our generator, we have a single yield
call which will yield the result of the numbers.map
call, which is a new Array. Because there is only a single yield, the only logged value is [2,3,4]
我们的for循环记录生成器生成的每个值。在我们的生成器中,我们有一个单一的收益率调用,它将产生数字的结果。映射调用,这是一个新的数组。因为只有一个收益率,所以记录的唯一值是[2,3,4]
2. yield*
2。产量*
So yield
obviously won't work in the case above. We'll have to try something else.
显然,收益率在上面的情况下是行不通的。我们得试试别的。
function* generator(numbers) {
yield* numbers.map(x => x + 1);
}
for (let n of generator([1,2,3])) console.log(n);
// 2
// 3
// 4
Again, our for
loop logs each value yield
ed by the generator. Inside our generator, we yield the same result of the numbers.map
call, but this time we use yield*
, which yield by delegation.
同样,我们的for循环记录生成器生成的每个值。在我们的生成器中,我们产生了相同的结果。map调用,但这次我们使用yield*,按委托授予。
What are we yielding then? Well, Array's have a built-in generator, Array.prototype[Symbol.iterator]
. So at this point, the for
loop is essentially directly stepping thru the generator provided by the Array. Since the array has 3 values, we see 3 logged values.
那么,我们屈服于什么呢?数组有一个内置的生成器,Array.prototype[Symbol.iterator]。在这一点上,for循环实际上是直接通过数组提供的生成器进行步进。由于数组有3个值,所以我们看到3个日志值。
Watchful eyes
警惕的眼睛
So we iterate thru numbers
once using Array.prototype.map
but then we iterate thru the intermediate array using the for
loop? Seems like a waste doesn't it?
我们使用array。prototype对数据进行迭代。映射,然后我们用for循环遍历中间数组?看起来像是浪费,不是吗?
Let's look back at your original code though
让我们回头看看你的原始代码。
function *generator() {
let numbers = [1,2,3,4,5];
numbers.map(n => yield (n + 1));
}
for (var n of generator()) {
console.log(n);
}
Notice that your numbers.map
call is pretty meaningless. Array.prototype.map
creates a new array, but your generator doesn't do anything with it. So really you're just using map
to iterate thru the numbers, not because you actually care about the returned value of map
注意您的数字。地图调用毫无意义。Array.prototype。map创建了一个新的数组,但是您的生成器不会对它做任何事情。你只是用map来迭代数字,不是因为你关心的是map的返回值
Say what you mean, mean what you say
说出你的意思,说出你的意思
OK, so now we know we only really care about iterating thru the numbers. So we'll use iteration the way JavaScript knows best
好了,现在我们知道我们只关心遍历这些数字。因此我们将使用JavaScript最了解的迭代方法
function* generator(numbers) {
for (let x of numbers)
yield x + 1
}
for (let n of generator([1,2,3])) console.log(n);
// 2
// 3
// 4
Bingo. No tricky yield*
. No double iteration. No nonsense.
宾果。没有复杂的收益率。没有双迭代。没有废话。
#3
4
That's because the arrow function is not a generator. If I expand your arrow function, it would look something like:
这是因为箭头函数不是生成器。如果我展开你的箭头函数,它会是这样的
function *generator() { // <-- this is your generator function
let numbers = [1,2,3,4,5];
numbers.map(function(n){ // <-- this one isn't a generator
yield (n + 1) // <-- there's your yield
}.bind(this));
}
#4
0
Just discovered you can encounter this by accidentally closing your function too early.
刚刚发现,您可能会因为不小心过早地关闭函数而遇到这种情况。
i.e. one too many }
即一个过多的}
#5
0
[1,2,3,4,5].map(function*(v){yield v+1;}).reduce((accumulator, currentValue) => accumulator = [...accumulator].concat([...currentValue]))
explanation...
解释……
[1,2,3,4,5].map(function*(v){yield v+1;})
pack all values into generator resulting
将所有值打包到生成器中
(5) [Generator, Generator, Generator, Generator, Generator]
(5)[发电机、发电机、发电机、发电机、发电机]
unpack into flat array
解压缩到平面阵列
.reduce((accumulator, currentValue) => accumulator = [...accumulator].concat([...currentValue]))
(5) [2, 3, 4, 5, 6]
(5)[2,3,4,5,6]
for normal use
对正常使用
[1,2,3,4,5].map(function*(v){yield v+1;}).forEach(v => console.log([...v][0]))
2
2
3
3
4
4
5
5
6
6
[...v][0] is a bit ugly but it is works.
[…[0]有点难看,但很管用。
#1
7
It is because arrow functions are not generator functions. For example,
这是因为箭头函数不是生成器函数。例如,
function temp() {
yield 1;
}
Can we expect this to work? No. Because temp
is not a generator function. The same is applicable to arrow functions as well.
我们能指望它起作用吗?不。因为temp不是生成器函数。同样也适用于箭头函数。
FWIW, the usage of yield
in an Arrow function is an early error as per the ECMAScript 2015 specification, as per this section,
FWIW,在箭头函数中使用yield是根据ECMAScript 2015规范的早期错误,根据本节,
ArrowFunction : ArrowParameters => ConciseBody
ArrowFunction: ArrowParameters => ConciseBody。
It is a Syntax Error if ArrowParameters Contains YieldExpression is true.
如果ArrowParameters包含屈服表达式,那么它就是一个语法错误。
It is a Syntax Error if ConciseBody Contains YieldExpression is true.
如果ConciseBody包含YieldExpression,则是语法错误。
#2
11
You can do anything but not everything – Learn to delegate
你可以做任何事,但不能做任何事——学会委派
Let's first look at two examples
让我们先看两个例子
1. yield
1。收益率
function* generator(numbers) {
yield numbers.map(x => x + 1);
}
for (let n of generator([1,2,3])) console.log(n);
// [ 2, 3, 4 ]
Our for
loop logs each value yielded by the generator. Inside our generator, we have a single yield
call which will yield the result of the numbers.map
call, which is a new Array. Because there is only a single yield, the only logged value is [2,3,4]
我们的for循环记录生成器生成的每个值。在我们的生成器中,我们有一个单一的收益率调用,它将产生数字的结果。映射调用,这是一个新的数组。因为只有一个收益率,所以记录的唯一值是[2,3,4]
2. yield*
2。产量*
So yield
obviously won't work in the case above. We'll have to try something else.
显然,收益率在上面的情况下是行不通的。我们得试试别的。
function* generator(numbers) {
yield* numbers.map(x => x + 1);
}
for (let n of generator([1,2,3])) console.log(n);
// 2
// 3
// 4
Again, our for
loop logs each value yield
ed by the generator. Inside our generator, we yield the same result of the numbers.map
call, but this time we use yield*
, which yield by delegation.
同样,我们的for循环记录生成器生成的每个值。在我们的生成器中,我们产生了相同的结果。map调用,但这次我们使用yield*,按委托授予。
What are we yielding then? Well, Array's have a built-in generator, Array.prototype[Symbol.iterator]
. So at this point, the for
loop is essentially directly stepping thru the generator provided by the Array. Since the array has 3 values, we see 3 logged values.
那么,我们屈服于什么呢?数组有一个内置的生成器,Array.prototype[Symbol.iterator]。在这一点上,for循环实际上是直接通过数组提供的生成器进行步进。由于数组有3个值,所以我们看到3个日志值。
Watchful eyes
警惕的眼睛
So we iterate thru numbers
once using Array.prototype.map
but then we iterate thru the intermediate array using the for
loop? Seems like a waste doesn't it?
我们使用array。prototype对数据进行迭代。映射,然后我们用for循环遍历中间数组?看起来像是浪费,不是吗?
Let's look back at your original code though
让我们回头看看你的原始代码。
function *generator() {
let numbers = [1,2,3,4,5];
numbers.map(n => yield (n + 1));
}
for (var n of generator()) {
console.log(n);
}
Notice that your numbers.map
call is pretty meaningless. Array.prototype.map
creates a new array, but your generator doesn't do anything with it. So really you're just using map
to iterate thru the numbers, not because you actually care about the returned value of map
注意您的数字。地图调用毫无意义。Array.prototype。map创建了一个新的数组,但是您的生成器不会对它做任何事情。你只是用map来迭代数字,不是因为你关心的是map的返回值
Say what you mean, mean what you say
说出你的意思,说出你的意思
OK, so now we know we only really care about iterating thru the numbers. So we'll use iteration the way JavaScript knows best
好了,现在我们知道我们只关心遍历这些数字。因此我们将使用JavaScript最了解的迭代方法
function* generator(numbers) {
for (let x of numbers)
yield x + 1
}
for (let n of generator([1,2,3])) console.log(n);
// 2
// 3
// 4
Bingo. No tricky yield*
. No double iteration. No nonsense.
宾果。没有复杂的收益率。没有双迭代。没有废话。
#3
4
That's because the arrow function is not a generator. If I expand your arrow function, it would look something like:
这是因为箭头函数不是生成器。如果我展开你的箭头函数,它会是这样的
function *generator() { // <-- this is your generator function
let numbers = [1,2,3,4,5];
numbers.map(function(n){ // <-- this one isn't a generator
yield (n + 1) // <-- there's your yield
}.bind(this));
}
#4
0
Just discovered you can encounter this by accidentally closing your function too early.
刚刚发现,您可能会因为不小心过早地关闭函数而遇到这种情况。
i.e. one too many }
即一个过多的}
#5
0
[1,2,3,4,5].map(function*(v){yield v+1;}).reduce((accumulator, currentValue) => accumulator = [...accumulator].concat([...currentValue]))
explanation...
解释……
[1,2,3,4,5].map(function*(v){yield v+1;})
pack all values into generator resulting
将所有值打包到生成器中
(5) [Generator, Generator, Generator, Generator, Generator]
(5)[发电机、发电机、发电机、发电机、发电机]
unpack into flat array
解压缩到平面阵列
.reduce((accumulator, currentValue) => accumulator = [...accumulator].concat([...currentValue]))
(5) [2, 3, 4, 5, 6]
(5)[2,3,4,5,6]
for normal use
对正常使用
[1,2,3,4,5].map(function*(v){yield v+1;}).forEach(v => console.log([...v][0]))
2
2
3
3
4
4
5
5
6
6
[...v][0] is a bit ugly but it is works.
[…[0]有点难看,但很管用。