Могу ли я использовать синтаксис функции ES6 с генераторами? (обозначение стрелки)

то есть, как я могу выразить это:

function *(next) {}

со стрелками. Я пробовал все комбинации, о которых я мог думать, и я не могу найти на нем никакой документации.

(в настоящее время используется node v0.11.14)

Ответ 1

Можно ли использовать синтаксис функции ES6 с генераторами?

Вы не можете. Сожалею.

Согласно MDN

Оператор function* (function, за которым следует звездочка) определяет функцию-генератор.

Из спецификационного документа (мой акцент):

Синтаксис функции расширяется, чтобы добавить необязательный токен *:

FunctionDeclaration: "function" "*"? Identifier "(" FormalParameterList? ")" 
  "{" FunctionBody "}"

Ответ 2

Разница между Inline-функциями и функциями Arrow

Прежде всего Функции стрелок () => {} не заменяют встроенные функции function(){}, и они разные. Встроенные функции - это просто функции, поэтому вопрос заключается в том, какая разница между функциями Arrow и Inline-функциями.

Выражение функции стрелки (также известное как функция стрелки) имеет более короткий синтаксис по сравнению с выражением функции и не связывает его собственные this, arguments, super или new.target). Функции стрелок всегда анонимны.

Несколько более быстрых деталей здесь


Почему функция Arrow не может использоваться как генераторы

https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/Arrow_functions

Использование ключевого слова yield

Ключевое слово yield не может использоваться в теле функции стрелки (за исключением случаев, когда разрешено внутри функций, вложенных в него внутри). Как следствие, функции стрелок не могут использоваться в качестве генераторов.

Обратите внимание, что генераторы без yield не имеют смысла.


Почему функция Arrow не может использовать yield

http://tc39wiki.calculist.org/es6/arrow-functions/

Функции стрелок связывают this лексически, связывают return в корпусе блока, поэтому он возвращает из непосредственно включающей функции стрелки и исключает break и continue из ссылок на заявления за пределами непосредственно включающей функции стрелок.

Первичное выражение Identifier arguments не может использоваться в теле функции стрелки (будь то выражение или блочная форма).

Аналогично, yield не может использоваться в теле функции стрелки. Стрелки не могут быть генераторами, и мы не хотим глубоких продолжений.

Выход в функцию со стрелкой вызовет семантическую ошибку: http://www.ecma-international.org/

В конце причина заключается в глубокой сложности в реализации ECMA6. С# не позволяет это также для нескольких аналогичных причин.

Ответ 3

В дополнение к обсуждению esdiscuss.org и Ecma TC39 комитет ES6, принятый в ноябре 2013 г., упомянутый выше, генераторные стрелы были повторно рассмотрены на двух заседаниях ES7 в сентябре 2016 г. [1] [2]. После обсуждения плюсов и минусов различного синтаксиса (в основном =*> и =>*) и отсутствия оправданий и вариантов использования для этой функции они пришли к выводу, что:

  • В комитете есть какой-то интерес, но беспокойство в том, что функция не тянет его вес для добавления нового синтаксиса
  • Планируйте вернуться к 3-му дню, чтобы увидеть, можем ли мы получить =>* до этапа 0, по крайней мере, в рамках предложения по асинхронному прогрессу [Domenic Denicola].
Предложение о генераторных стрелках было перенесено на этап 1 с Бренданом Эихом и Домеником Дениколой в качестве чемпионов, но релевантный tc39/proposals repo doesn ' t существует. Я предполагаю, что для дальнейших новостей нужно подождать, пока не будет завершено предложение асинхронной итерации этапа 3.

Ответ 4

У меня тоже был такой же вопрос и я пришел сюда. После прочтения постов и комментариев я почувствовал, что использование генератора в функции со стрелкой выглядит расплывчато:

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) и часто однострочными, тогда как генераторы в значительной степени противоположны.

Я скажу, что целью генератора является запуск-остановка-запуск, и поэтому я не думаю, что нам нужно заботиться о прототипе, лексическом выражении и т.д.

Ответ 5

Я знаю, что это очень поздно, но другой возможной причиной может быть синтаксис. возможно (*() => {}) работает, но как насчет (9 **() => {})? Это 9 к степени функции стрелки, возвращающей NaN, или это 9-кратная функция стрелки генератора, также возвращающая NaN? Это можно сделать с помощью некоторого альтернативного синтаксиса, например =>* как уже упоминалось в другом ответе, но, возможно, было желание сохранить согласованность синтаксиса функции генератора (например, function*() {} и { *genMethod() {} }) когда это было реализовано. Не слишком оправдание, но причина для этого.

Ответ 6

Есть хороший обходной путь с Redx-сага

import { call, all } from 'redux-saga/effects';

function* gen() {
   yield all([].map(() => {
      return call(....);
   }));
}

Ответ 7

Я попробовал это:

{
    [Symbol.iterator]: function * () {
        for (let element of elements) {
            yield element;
        }
    }.bind(this)
}