つまり、これをどのように表現すればよいですか。
function *(next) {}
矢印付き。私は考えられるすべての組み合わせを試しましたが、それに関するドキュメントは見つかりません。
(現在ノードv0.11.14を使用)
param*=>{ }
つもりですか?
function(){}
が同じことをしていないことを知ってい()=>{}
ますか?
つまり、これをどのように表現すればよいですか。
function *(next) {}
矢印付き。私は考えられるすべての組み合わせを試しましたが、それに関するドキュメントは見つかりません。
(現在ノードv0.11.14を使用)
param*=>{ }
つもりですか?
function(){}
が同じことをしていないことを知ってい()=>{}
ますか?
回答:
ES6のアロー関数構文をジェネレーターで使用できますか?
できません。ごめんなさい。
MDNによると
function*
声明(function
アスタリスクが続くキーワード)はジェネレータ関数を定義します。
仕様ドキュメントから(私の強調):
関数の構文は、オプション追加するように拡張された
*
トークンを:
FunctionDeclaration: "function" "*"? Identifier "(" FormalParameterList? ")"
"{" FunctionBody "}"
.prototype
たとえば、ない)、多くの場合は1行であると想定されていますが、ジェネレーターはほとんど逆です。
this
作成する必要がありましたlet self = this
。字句スコープ+矢印構文は良かったでしょう。残念ながら、世界の終わりではありません。
function
キーワードを言語の「悪い部分」に降格させます。これには正当な理由があります。これらの人々にとって、矢印ジェネレーターの欠如は厄介な矛盾です。
まず第一に、アロー関数 () => {}
はインライン関数に取って代わるものではなくfunction(){}
、それらは異なります。インライン関数は単に関数なので、問題はアロー関数とインライン関数の違いは何ですか。
(また、矢印機能として知られている)、矢印関数式は、関数式に比べて短い構文を持ち、独自に結合しない
this
、arguments
、super
、またはnew.target
)。アロー関数は常に匿名です。
詳細はこちら
https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/Arrow_functions
yieldキーワードの使用
収量キーワードは(さらにその中にネストされた関数内で許可する場合を除いて)矢印関数の本体で使用されなくてもよいです。結果として、矢印関数はジェネレーターとして使用できません。
を持たないジェネレータyield
は意味をなさないことに注意してください。
http://tc39wiki.calculist.org/es6/arrow-functions/
矢印関数は
this
字句的にバインドreturn
し、ブロック本体のケースにバインドして、直接囲んでいる矢印関数から戻り、直接囲んでいる矢印関数の外側のステートメントを除外break
およびcontinue
参照します。識別子の一次式は、
arguments
矢印関数の本体(か発現またはブロック形)で使用されなくてもよいです。同様
yield
に、アロー関数の本体では使用できません。矢をジェネレータにすることはできませんし、私たちは深い継続を望んでいません。
Arrow-FunctionのYieldはセマンティックエラーをスローします:http : //www.ecma-international.org/
結局のところ、理由はECMA6の実装における深い複雑さにあります。C#でもこれと同じような理由でこれを許可していません。
()=>{}
すると、インライン関数との違い、およびジェネレーターに制限がある理由を理解するのに非常に役立つと私はまだ思います。
*() => { yield bla; }
大丈夫ではないのかを理解しようとしていますasync () => { await bla; }
が、それは...
上記の2013年11月のesdiscuss.orgとEcma TC39委員会のES6会議ノートに関する議論に加えて、ジェネレーターアローが2016年9月の2回のES7会議で再検討されました[1] [2]。さまざまな構文(主に=*>
および=>*
)の長所と短所、およびこの機能の正当化と使用例の欠如について話し合った後、次の結論に達しました。
- 委員会からいくらか関心がありますが、この機能が新しい構文を追加するための重さを引き出していないことに懸念があります。
=>*
[Domenic Denicola]の非同期反復提案の一部として、少なくともステージ0に到達できるかどうかを確認するために、3日目に再訪問することを計画します。
ジェネレーターアローの提案は、ブレンダンアイヒとドメニックデニコラをチャンピオンとしてステージ1に移動しました。上記の非同期イテレーションは2018年に完成し、実装されました。
2019年10月、Sergey Rubanovによる公式リポジトリが登場し、構文やその他の詳細についてさらに議論が行われました。
私も同じ質問をしていて、ここに来ました。投稿とコメントを読んだ後、私はarrow関数でジェネレーターを使用することは曖昧に思われます:
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
これが、アロー関数に関連してジェネレータを実装しなかった大きな理由かもしれません。
しかし、私がその1人だったとしたら、次のように考えることができたでしょう。
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がない)、多くの場合1行であると想定されていますが、ジェネレーターはほとんど逆です。
使用するジェネレーターの目的はrun-stop-runであると言いますので、プロトタイプやレキシカルなthisなどを気にする必要はないと思います。
() ~> { yield 'a'; yield 'b'; }
。正直なところ、チルダが大好きです。
これは非常に遅いことはわかっていますが、もう1つの考えられる理由は構文です。多分(*() => {})
動作しますが、どう(9 ** () => {})
ですか?これは、9のアロー関数の累乗でNaN
戻りNaN
ますか、それとも9倍のジェネレーターアロー関数で戻りますか?=>*
ここで別の回答で述べたように、これはいくつかの代替構文で行うことができますが、ジェネレーター関数構文(function* () {}
およびなど{ *genMethod() {} }
)の実装時に一貫性を維持したいという要望があったかもしれません。言い訳はあまりしませんが、理由はあります。
redux-sagaには良い回避策があります
import { call, all } from 'redux-saga/effects';
function* gen() {
yield all([].map(() => {
return call(....);
}));
}
function*
ステートメント(アスタリスクが後に続く関数キーワード)は、ジェネレーター関数を定義します。」