也就是说,我应该如何表达呢?
function *(next) {}
使用箭头语法?我已经尝试了我能想到的所有组合,但找不到任何相关文档。
(我目前正在使用Node.js v0.11.14。)
也就是说,我应该如何表达呢?
function *(next) {}
使用箭头语法?我已经尝试了我能想到的所有组合,但找不到任何相关文档。
(我目前正在使用Node.js v0.11.14。)
我能在生成器中使用ES6的箭头函数语法吗?
很抱歉,您不能。
根据 MDN
function*
语句(function
关键字后跟一个星号)定义了一个生成器函数。
从spec document中可以看到(我的重点):
function 语法被扩展以添加可选的
*
标记:
FunctionDeclaration: "function" "*"? Identifier "(" FormalParameterList? ")"
"{" FunctionBody "}"
.prototype
),通常只有一行代码,而生成器则相反。 - Bergithis
,并且不得不编写let self = this
的方法来在生成器内部获取它。词法作用域+箭头语法会很好用,但很遗憾,这并不是世界末日。 - dvlsgfunction
关键字降为语言中的“坏部分”。这么做有很好的原因。对于这些人来说,箭头生成器的缺失是一个令人烦恼的不一致之处。 - callumfunction
声明的好理由。 - Bergi首先,箭头函数 () => {}
不是用来替代内联函数 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
,在Block体中绑定return
,因此它从立即封闭的箭头函数返回,并且防止break
和continue
引用立即封闭的箭头函数之外的语句。
Identifier主表达式arguments
不能在箭头函数的主体中使用(无论是表达式还是块形式)。
同样,在箭头函数的主体中不能使用yield
。箭头函数不能作为生成器,并且我们不想要深层次的连续性。
在箭头函数中使用yield
将抛出语义错误:http://www.ecma-international.org/
最后,原因在于ECMA6的实现过于复杂。C#也不允许这样做,原因有些类似reasons。
*() => { yield bla; }
不可以,而 async () => { await bla; }
可以…… - Lee Bensonyield
语句,而它也无法有 yield
语句,因为它不能成为生成器。 - Sapphire_Brickyield
,但是语法为什么不能被设计成允许呢?为什么设计者不希望箭头函数能够成为生成器? - chharvey=*>
和=>*
)的利弊以及缺乏此功能的证明和用例进行讨论后,他们得出结论:
- 委员会对此有一定的兴趣,但担心该功能对于添加新的语法不够有利
- 计划在第三天重新审视,看看我们是否可以至少将
=>*
置于阶段0作为[Domenic Denicola]的异步迭代提案的一部分
生成器箭头的提案已被移动到阶段 1,由 Brendan Eich 和 Domenic Denicola 担任支持者。如上所述,异步迭代在2018年时已经完成并实现。
在2019年10月,由 Sergey Rubanov 创建的官方仓库出现,并有更多关于语法和其他细节的讨论。
我也有同样的问题,所以来到这里。在阅读了帖子和评论后,我感觉在箭头函数中使用生成器似乎不太清晰:
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
或generator
的关键字,箭头函数不使用它。
总之:
即使他们希望在箭头函数中实现生成器,我认为他们需要重新考虑核心js中的生成器语法:
generator function myfunc() {}
// rather than
function* myfunc() {} // or, function *myfunc() {}
这将是一个很大的错误。因此,将箭头函数从生成器中排除出去,非常不错。
根据@Bergi的评论:
不行。箭头函数应该轻量级(例如没有 .prototype),通常只有一行代码,而生成器则完全相反。
我会说,生成器的使用目的是运行-停止-运行,所以我认为我们不需要关心原型、词法this等内容。
() ~> { yield 'a'; yield 'b'; }
。老实说,我就是喜欢波浪号。 - Gershom Maesconst someGeneratorFunction = gen() => ...
很漂亮。 - user3025289=>=>
,因为普通函数产生一个值,所以它的参数是=>
[获取返回值的逻辑],而生成器可能会产生多个值,并且生成器会先运行,然后停止,再次运行。 - mtraceur(*() => {})
可以工作,但是(9 ** () => {})
呢?这是一个箭头函数的9次方,返回NaN
,还是一个生成器箭头函数的9倍,也返回NaN
?可以使用一些替代语法,如另一个答案中提到的=>*
,但也许有人希望保持生成器函数语法的一致性(例如function* () {}
和{ *genMethod() {} }
)在实现时。这并不是一个很好的借口,但却是一个原因。function* iterable(arg) {
yield* [];
}
async function* asyncIterable(arg) {
yield* [];
}
const arrowIterable = arg => {
return {
*[Symbol.iterator]() {
yield* [];
},
};
};
const arrowAsyncIterable = arg => {
return {
async *[Symbol.asyncIterator]() {
yield* [];
},
};
};
Symbol.iterator
或者 Symbol.asyncIterator
设置为迭代器的对象。生成器是迭代器!
祝愉快!
使用redux-saga有一个不错的解决方案
import { call, all } from 'redux-saga/effects';
function* gen() {
yield all([].map(() => {
return call(....);
}));
}
param*=>{}
能做什么? - CoderPifunction() {}
和()=>{}
不是做同样的事情吗? - CoderPi