也就是我怎么表达
function *(next) {}
用箭头语法?我已经尝试了所有我能想到的组合,但我找不到任何关于它的文档。
(我目前正在使用 Node.js v0.11.14。)
也就是我怎么表达
function *(next) {}
用箭头语法?我已经尝试了所有我能想到的组合,但我找不到任何关于它的文档。
(我目前正在使用 Node.js v0.11.14。)
Can I use ES6's arrow function syntax with generators?
You can't. Sorry.
According to MDN
The
function*
statement (function
keyword followed by an asterisk) defines a generator function.
From a spec document (my emphasis):
The function syntax is extended to add an optional
*
token:
FunctionDeclaration: "function" "*"? Identifier "(" FormalParameterList? ")"
"{" FunctionBody "}"
首先,箭头函数 () => {}
不是用来代替内联函数的function(){}
,它们是不同的。内联函数只是函数,所以问题是箭头函数和内联函数之间的区别是什么。
与函数表达式相比,箭头函数表达式(也称为箭头函数)具有更短的语法,并且不绑定自己的
this
、arguments
、super
或new.target
)。箭头函数始终是匿名的。
这里有一些更快速的细节
https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/Arrow_functions
使用 yield 关键字
yield关键字不能用在箭头函数的主体中(除非允许在进一步嵌套的函数中使用)。因此,箭头函数不能用作生成器。
请注意,没有生成器没有yield
意义。
http://tc39wiki.calculist.org/es6/arrow-functions/
箭头函数在
this
词法上绑定return
,在Block主体情况下绑定,因此它从直接封闭的箭头函数返回,并排除break
和continue
引用直接封闭的箭头函数之外的语句。标识符主表达式
arguments
不能用于箭头函数的主体(无论是表达式还是块形式)。同样,
yield
不能在箭头函数的主体中使用。箭头不能成为生成器,我们不希望深度延续。
箭头函数的产量将引发语义错误: http: //www.ecma-international.org/
归根结底,原因在于 ECMA6 实现的深度复杂性。由于类似的原因,C# 也不允许这样做。
除了上面提到的esdiscuss.org上的讨论和2013 年 11 月的 Ecma TC39 委员会 ES6 会议记录之外,在 2016 年 9 月的两次 ES7 会议中重新讨论了生成器箭头[1] [2]。=*>
在讨论了各种语法(主要是and )的优缺点以及=>*
缺乏对此功能的理由和用例之后,他们得出的结论是:
- 委员会有一些兴趣,但担心该功能不会因为添加新语法而发挥作用
- 作为 [Domenic Denicola] 的异步迭代提案的一部分,计划在第 3 天重新访问,看看我们是否
=>*
至少可以进入第 0 阶段
生成器箭头的提案被移至第 1 阶段,由 Brendan Eich 和 Domenic Denicola 作为冠军。上述异步迭代已于 2018 年完成并实施。
2019 年 10 月,Sergey Rubanov 的官方 repo出现了,其中包含更多关于语法和其他细节的讨论。
我也有同样的问题,来到这里。看完帖子和评论后,我觉得在箭头函数中使用生成器似乎很模糊:
const generator = () => 2*3; // * implies multiplication
// so, this would be a confusing
const generator = () =>* something; // err, multiplying?
const generator = () =*> ... // err, ^^
const generator = ()*=> ... // err, *=3, still multiplying?
const generator=*()=> ... // err, ^^
const generator = *param => ... //err, "param" is not fixed word
这可能是他们没有实现与箭头函数相关的生成器的主要原因。
但是,如果我是他们中的一员,我可能会这样想:
const generator = gen param => ... // hmm, gen indicates a generator
const generator = gen () => ... // ^^
这感觉就像我们有异步函数:
const asyncFunction = async () => ... // pretty cool
因为,在普通函数中存在async关键字,所以箭头函数正在使用它 -async () =>
可能看起来async function()
.
但是,没有类似gen
or的关键字generator
,可惜箭头函数没有使用它。
总结:
即使他们希望在箭头函数中实现生成器,我认为他们需要重新考虑核心 js 中的生成器语法:
generator function myfunc() {}
// rather than
function* myfunc() {} // or, function *myfunc() {}
这将是一个大错误。因此,将箭头函数从生成器中排除出来是非常酷的。
在@Bergi 评论之后:
不。箭头函数应该是轻量级的(例如没有 .prototype)并且通常是单行的,而生成器则恰恰相反。
我会说生成器的使用目的是运行-停止-运行,所以我认为我们不需要关心原型、词法 this 等。
现在你不能,但将来你可能会因为 TC39 在 2019 年 10 月发布相同的提案,这是在第 1 阶段。
我知道这已经很晚了,但另一个可能的原因可能是语法。也许(*() => {})
有效,但是呢(9 ** () => {})
?是箭头函数的 9 次方,返回NaN
,还是生成器箭头函数的 9 倍,也返回NaN
?可以使用一些替代语法来完成,就像=>*
这里的另一个答案所提到的那样,但也许希望在实现生成器函数语法(例如function* () {}
and { *genMethod() {} }
)时保持其一致性。不是太多的借口,而是一个理由。
There is a nice workaround with redux-saga
import { call, all } from 'redux-saga/effects';
function* gen() {
yield all([].map(() => {
return call(....);
}));
}