也就是说,我怎么表达
function *(next) {}
用箭头语法?我已经尝试了所有我能想到的组合,但我找不到任何关于它的文档。
(我目前使用的是Node.js v0.11.14。)
也就是说,我怎么表达
function *(next) {}
用箭头语法?我已经尝试了所有我能想到的组合,但我找不到任何关于它的文档。
(我目前使用的是Node.js v0.11.14。)
我可以使用ES6的箭头函数语法生成器吗?
你不能。对不起。
根据MDN
function*语句(function关键字后面带星号)定义了一个生成器函数。
从一个规范文档(我的重点):
函数语法被扩展为添加一个可选的*令牌:
FunctionDeclaration: "function" "*"? Identifier "(" FormalParameterList? ")"
"{" FunctionBody "}"
内联函数和箭头函数的区别
首先,Arrow-functions() =>{}不是用来替换内联函数function(){},它们是不同的。 内联函数就是简单的函数,所以问题是箭头函数和内联函数之间的区别是什么。
与函数表达式相比,箭头函数表达式(也称为箭头函数)具有更短的语法,并且不绑定自己的this、参数、super或new.target)。箭头函数总是匿名的。
这里有更多的细节
为什么箭头函数不能用作生成器
https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/Arrow_functions
使用yield关键字 yield关键字不能在箭头函数体中使用(除非允许在箭头函数体中进一步嵌套的函数中使用)。因此,箭头函数不能用作生成器。
注意,没有yield的生成器是没有意义的。
为什么箭函数不能使用yield
http://tc39wiki.calculist.org/es6/arrow-functions/
箭头函数在词法上绑定它,在Block体情况下绑定return,以便它从直接封闭的箭头函数返回,并排除break和continue引用直接封闭的箭头函数之外的语句。 Identifier主表达式参数不能在箭头函数体中使用(无论是表达式形式还是块形式)。 同样,yield也不能用在箭头函数体中。箭头不能作为生成器,我们也不想要深度延续。
Yield在一个箭头函数将抛出语义错误:http://www.ecma-international.org/
究其原因,在于ECMA6实现的深度复杂性。由于类似的原因,c#也不允许这样做。
除了上面提到的esdiscuss.org上的讨论和Ecma TC39委员会2013年11月的ES6会议记录之外,发电机箭头在2016年9月的两次ES7会议[1][2]中被重新讨论。在讨论了各种语法的优缺点(主要是=*>和=>*)以及缺乏该功能的理由和用例之后,他们得出了这样的结论:
委员会对此有一些兴趣,但担心该特性在添加新语法方面没有发挥应有的作用 计划在第三天重新审视=>*,看看我们能不能至少把它带到阶段0,这是Domenic Denicola的异步迭代提议的一部分
发电机箭头的提议被移到第一阶段,Brendan Eich和Domenic Denicola作为冠军。上述异步迭代已于2018年完成并实现。
2019年10月,谢尔盖·鲁巴诺夫(Sergey Rubanov)的官方回购版出现了更多关于语法和其他细节的讨论。
I know that this is very late, but another possible reason could be syntax. maybe (*() => {}) works, but what about (9 ** () => {})? Is that 9 to the power of an arrow function, returning NaN, or is it 9 times a generator arrow function, also returning NaN? It could be done with some alternative syntax, like =>* as mentioned by another answer here, but maybe there was a desire to preserve the consistency of the generator function syntax (eg. function* () {} and { *genMethod() {} }) when it was being implemented. Not too much of an excuse, but a reason for it.
redux-saga有一个很好的解决方案
import { call, all } from 'redux-saga/effects';
function* gen() {
yield all([].map(() => {
return call(....);
}));
}
我也有同样的问题,所以来了这里。在阅读了帖子和评论后,我觉得在箭头函数中使用生成器似乎很模糊:
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关键字是存在的,所以arrow函数正在使用它- async() =>很可能看起来是async function()。
但是,没有关键字像gen或generator和alas箭头函数不使用它。
结论:
即使他们希望在箭头函数中实现生成器,我认为他们需要重新考虑core js中的生成器语法:
generator function myfunc() {}
// rather than
function* myfunc() {} // or, function *myfunc() {}
这将是一个巨大的错误。让箭头函数远离生成器,这很酷。
以下是@Bergi的评论:
不。箭头函数应该是轻量级的(例如没有.prototype),通常是一行程序,而生成器则几乎相反。
我会说生成器使用的目的是运行-停止-运行所以我认为我们不需要关心原型,词法这个等等。
你可以,但不是用好的方式。它不短,看起来也不漂亮。看看这个:
function* iterable(arg) {
yield* [];
}
async function* asyncIterable(arg) {
yield* [];
}
const arrowIterable = arg => {
return {
*[Symbol.iterator]() {
yield* [];
},
};
};
const arrowAsyncIterable = arg => {
return {
async *[Symbol.asyncIterator]() {
yield* [];
},
};
};
这是可行的,因为iterable基本上是一个带有Symbol的对象。迭代器或符号。asyncIterator设置为一个迭代器。生成器是迭代器!
享受吧!