то есть, как я могу выразить это:
function *(next) {}
со стрелками. Я пробовал все комбинации, о которых я мог думать, и я не могу найти на нем никакой документации.
(в настоящее время используется node v0.11.14)
то есть, как я могу выразить это:
function *(next) {}
со стрелками. Я пробовал все комбинации, о которых я мог думать, и я не могу найти на нем никакой документации.
(в настоящее время используется node v0.11.14)
Можно ли использовать синтаксис функции ES6 с генераторами?
Вы не можете. Сожалею.
Согласно MDN
Оператор
function*
(function
, за которым следует звездочка) определяет функцию-генератор.
Из спецификационного документа (мой акцент):
Синтаксис функции расширяется, чтобы добавить необязательный токен
*
:
FunctionDeclaration: "function" "*"? Identifier "(" FormalParameterList? ")"
"{" FunctionBody "}"
Прежде всего Функции стрелок () => {}
не заменяют встроенные функции function(){}
, и они разные.
Встроенные функции - это просто функции, поэтому вопрос заключается в том, какая разница между функциями Arrow и Inline-функциями.
Выражение функции стрелки (также известное как функция стрелки) имеет более короткий синтаксис по сравнению с выражением функции и не связывает его собственные
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
в корпусе блока, поэтому он возвращает из непосредственно включающей функции стрелки и исключаетbreak
иcontinue
из ссылок на заявления за пределами непосредственно включающей функции стрелок.Первичное выражение Identifier
arguments
не может использоваться в теле функции стрелки (будь то выражение или блочная форма).Аналогично,
yield
не может использоваться в теле функции стрелки. Стрелки не могут быть генераторами, и мы не хотим глубоких продолжений.
Выход в функцию со стрелкой вызовет семантическую ошибку: http://www.ecma-international.org/
В конце причина заключается в глубокой сложности в реализации ECMA6. С# не позволяет это также для нескольких аналогичных причин.
В дополнение к обсуждению esdiscuss.org и Ecma TC39 комитет ES6, принятый в ноябре 2013 г., упомянутый выше, генераторные стрелы были повторно рассмотрены на двух заседаниях ES7 в сентябре 2016 г. [1] [2]. После обсуждения плюсов и минусов различного синтаксиса (в основном =*>
и =>*
) и отсутствия оправданий и вариантов использования для этой функции они пришли к выводу, что:
Предложение о генераторных стрелках было перенесено на этап 1 с Бренданом Эихом и Домеником Дениколой в качестве чемпионов, но релевантный tc39/proposals repo doesn ' t существует. Я предполагаю, что для дальнейших новостей нужно подождать, пока не будет завершено предложение асинхронной итерации этапа 3.
- В комитете есть какой-то интерес, но беспокойство в том, что функция не тянет его вес для добавления нового синтаксиса
- Планируйте вернуться к 3-му дню, чтобы увидеть, можем ли мы получить
=>*
до этапа 0, по крайней мере, в рамках предложения по асинхронному прогрессу [Domenic Denicola].
У меня тоже был такой же вопрос и я пришел сюда. После прочтения постов и комментариев я почувствовал, что использование генератора в функции со стрелкой выглядит расплывчато:
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) и часто однострочными, тогда как генераторы в значительной степени противоположны.
Я скажу, что целью генератора является запуск-остановка-запуск, и поэтому я не думаю, что нам нужно заботиться о прототипе, лексическом выражении и т.д.
Я знаю, что это очень поздно, но другой возможной причиной может быть синтаксис. возможно (*() => {})
работает, но как насчет (9 **() => {})
? Это 9 к степени функции стрелки, возвращающей NaN
, или это 9-кратная функция стрелки генератора, также возвращающая NaN
? Это можно сделать с помощью некоторого альтернативного синтаксиса, например =>*
как уже упоминалось в другом ответе, но, возможно, было желание сохранить согласованность синтаксиса функции генератора (например, function*() {}
и { *genMethod() {} }
) когда это было реализовано. Не слишком оправдание, но причина для этого.
Есть хороший обходной путь с Redx-сага
import { call, all } from 'redux-saga/effects';
function* gen() {
yield all([].map(() => {
return call(....);
}));
}
Я попробовал это:
{
[Symbol.iterator]: function * () {
for (let element of elements) {
yield element;
}
}.bind(this)
}