Posso usare la sintassi della funzione freccia di ES6 con i generatori? (notazione a freccia)


243

cioè come posso esprimere questo:

function *(next) {}

con le frecce. Ho provato tutte le combinazioni che mi sono venute in mente e non riesco a trovare alcuna documentazione su di esso.

(attualmente utilizzando il nodo v0.11.14)


5
Non puoi. Scusate. "L' function*istruzione (parola chiave della funzione seguita da un asterisco) definisce una funzione del generatore."

2
Nota che c'è stata una lunga discussione su questo argomento su esdiscuss.org .
voithos,

4
Cosa ti aspetti param*=>{ }di fare?
CoderPi

4
sai che function(){}non sta facendo lo stesso di ()=>{}?
CoderPi

8
" è davvero che i generatori ES6 sono 2 passi avanti e 1 passo indietro? " - no, i generatori possono solo fare un passo avanti :-)
Bergi,

Risposte:


231

Posso usare la sintassi della funzione freccia di ES6 con i generatori?

Non puoi. Scusate.

Secondo MDN

L' function*istruzione ( functionparola chiave seguita da un asterisco) definisce una funzione del generatore.

Da un documento di specifica (la mia enfasi):

La sintassi della funzione viene estesa per aggiungere un *token opzionale :

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

175
Mi sembra un difetto di progettazione.
Jonathon,

23
@Jonathon: No. Le funzioni delle frecce dovrebbero essere leggere (e non hanno un .prototypeesempio) e spesso una linea, mentre i generatori sono praticamente l'opposto.
Bergi,

38
Ho già incontrato alcuni scenari in cui un generatore su cui stavo giocando aveva bisogno dell'accesso al precedente thise ho dovuto scrivere l' let self = thishack per accedervi all'interno del generatore. La sintassi lessicale di scope + freccia sarebbe stata piacevole. Peccato, ma non esattamente la fine del mondo.
dvlsg,

3
Qualche ulteriore contesto attorno a questo a esdiscuss
Nick Tomlin,

20
@Bergi il ragionamento dietro le funzioni delle frecce è molto più complicato di così. Non si tratta davvero di brevità. Le funzioni delle frecce non devono essere leggere: è vero che esiste una sintassi del corpo a singola istruzione opzionale, ma che importa. Molte persone usano le frecce per tutte le definizioni delle funzioni eccetto i metodi di classe e riducono la functionparola chiave in una "parte negativa" della lingua. Ci sono buoni motivi per farlo. Per queste persone, la mancanza di generatori di frecce è una fastidiosa incoerenza.
callum

132

La differenza tra funzioni incorporate e funzioni freccia

Prima di tutto le funzioni freccia () => {} non sono fatte per sostituire le funzioni in linea function(){}e sono diverse. Le funzioni in linea sono semplicemente funzioni, quindi la domanda è qual è la differenza tra le funzioni freccia e le funzioni in linea.

Un'espressione funzione di freccia (noto anche come funzione di freccia) ha una sintassi più breve rispetto alle espressioni di funzione e non si lega la propria this, arguments, super, o new.target). Le funzioni freccia sono sempre anonime.

Alcuni dettagli più rapidi qui


Perché la funzione freccia non può essere utilizzata come generatori

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

Uso della parola chiave yield

La parola chiave yield non può essere utilizzata nel corpo di una funzione freccia (tranne quando consentito all'interno di funzioni ulteriormente nidificate al suo interno). Di conseguenza, le funzioni freccia non possono essere utilizzate come generatori.

Nota che i generatori senza yieldsenso non hanno senso.


Perché la funzione Freccia non può usare la resa

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

Le funzioni freccia si legano in modo thislessicale, si legano returnnel caso Corpo blocco in modo che ritorni dalla funzione freccia che si chiude immediatamente e precludano breake che facciano continueriferimento a dichiarazioni esterne alla funzione freccia che si racchiude immediatamente.

L' espressione primaria dell'identificatorearguments non può essere utilizzata nel corpo di una funzione freccia (sia che si tratti dell'espressione o del blocco).

Allo stesso modo, yieldnon può essere utilizzato nel corpo di una funzione freccia. Le frecce non possono essere generatori e non vogliamo continuazioni profonde.

La resa in una funzione freccia genererà un errore semantico: http://www.ecma-international.org/

Alla fine la ragione sta nella profonda complessità nell'attuazione dell'ECMA6. C # non lo consente anche per ragioni in qualche modo simili .


3
Ho usato un motore di ricerca e ho pubblicato un'altra spiegazione per te
CoderPi

1
Continuo a pensare che l'aggiunta di spiegazioni ()=>{}sarebbe di grande aiuto, per capire la sua differenza rispetto a una funzione in-line e perché la limitazione è presente per i generatori.
vitaly-t

63
Sto cercando di capire perché *() => { yield bla; }non va bene, ma async () => { await bla; }è ...
Lee Benson,

7
@CodeiSir, Re " e non vogliamo continuazioni profonde ", scuse pessime.
Pacerier,

9
Il tuo argomento è ciclico. Dici che le funzioni freccia non possono essere generatori perché non possono contenere la parola chiave yield. Ma non possono avere la parola chiave yield, perché non possono essere generatori: "Le frecce non possono essere generatori e non vogliamo continuazioni profonde".
Thayne,

36

Oltre alla discussione su esdiscuss.org e le note sulla riunione ES6 del comitato Ecma TC39 del novembre 2013 sopra menzionate, le frecce del generatore sono state rivisitate in due riunioni ES7 del settembre 2016 [1] [2] . Dopo una discussione su pro e contro di varie sintassi (principalmente =*>e =>*) e una mancanza di giustificazioni e casi d'uso per questa funzione, sono giunti alla conclusione che:

  • Vi è un certo interesse da parte del comitato, ma si teme che la funzionalità non abbia il suo peso per l'aggiunta di un nuovo sintassi
  • Intendi rivisitare il Day 3 per vedere se possiamo arrivare =>*almeno allo stage 0, come parte della proposta di iterazione asincrona di [Domenic Denicola]

La proposta di frecce generatrici è stata spostata nella fase 1 con Brendan Eich e Domenic Denicola come campioni. L'iterazione asincrona di cui sopra è stata completata e implementata nel 2018.

Nell'ottobre 2019 è apparso un repository ufficiale di Sergey Rubanov con ulteriori discussioni sulla sintassi e altri dettagli.


8

Avevo anche la stessa domanda e sono venuto qui. Dopo aver letto i post e i commenti, ho sentito che usare il generatore in una funzione freccia sembra essere vago:

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

Questa è forse la ragione principale per cui non hanno implementato il generatore in relazione alla funzione freccia.


Ma se fossi stato uno di loro, avrei potuto pensare in questo modo:

const generator = gen param => ... // hmm, gen indicates a generator
const generator = gen () => ... // ^^

Sembra proprio che abbiamo una funzione asincrona:

const asyncFunction = async () => ... // pretty cool

Perché, con la normale funzione esiste la parola chiave asincrona , quindi la funzione freccia la sta utilizzando - async () =>sembra probabile async function().

Ma non esiste una parola chiave come geno generatore purtroppo la funzione freccia non la utilizza.

Concludere:

Anche se desiderano implementare il generatore nella funzione freccia, penso che debbano ripensare alla sintassi del generatore in core js:

generator function myfunc() {}
// rather than
function* myfunc() {} // or, function *myfunc() {}

E questo sarà un grosso errore. Quindi, mantenere la funzione della freccia fuori dal generatore, è piuttosto bello.


Seguendo il commento di @Bergi :

No. Le funzioni della freccia dovrebbero essere leggere (e non hanno un prototipo per esempio) e spesso una linea, mentre i generatori sono praticamente l'opposto.

Dirò che lo scopo del generatore da usare è run-stop-run e quindi non penso che dobbiamo preoccuparci del prototipo, di questo lessico, ecc.


2
Potrebbe anche prendere in considerazione opzioni esotiche, come () ~> { yield 'a'; yield 'b'; }. Ad essere sincero, adoro le tilde.
Gershom,

@Gershom Ecco come i linguaggi di programmazione come Perl vanno completamente storto
Sapphire_Brick il

2

So che è molto tardi, ma un'altra possibile ragione potrebbe essere la sintassi. forse (*() => {})funziona, ma che dire (9 ** () => {})? È 9 alla potenza di una funzione freccia, che ritorna NaN, oppure è 9 volte una funzione freccia del generatore, che ritorna NaN? Potrebbe essere fatto con una sintassi alternativa, come =>*menzionato da un'altra risposta qui, ma forse c'era il desiderio di preservare la coerenza della sintassi della funzione del generatore (ad es. function* () {}E { *genMethod() {} }) quando veniva implementata. Non troppa scusa, ma una ragione per questo.


1
: +1: per i doppi asterischi ... JS della vecchia scuola qui. Chi dice che non puoi insegnare a un vecchio cane nuovi trucchi: gioia:
Shanimal,

L'unico motivo per cui non lo fanno è perché rendere difficile il parser. È del tutto possibile e non richiede compromessi nella sintassi.
Jason McCarrell

@JasonMcCarrell Se si preoccupassero abbastanza di non rendere il parser troppo complesso, allora forse Brendan Eich avrebbe dovuto mettere Scheme nel browser.
Sapphire_Brick il

1

In questo momento non puoi, ma in futuro potresti essere perché la proposta di rilascio del TC39 è la stessa nell'ottobre 2019, che è nella fase 1.


-4

C'è una bella soluzione con redux-saga

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

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

4
Come facciamo a sapere che OP utilizza Redux?
Maros,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.