2016-04-30 11 views
4
function* generatorFunction() { 
    yield (yield 1)(yield 2)(yield 3)(); 
} 
var iterator = generatorFunction(); 

// [1, 2, 3] 
var iteratedOver = [iterator.next().value, iterator.next().value, iterator.next().value]; 

Ich bin mir nicht sicher, wie das funktioniert.ES6 Ausbeute (Ausbeute 1) (Ausbeute 2) (Ausbeute 3)()

yield gibt keine Funktionsreferenz, also was sind die Klammern Aussagen wie (yield 2) tun - sind sie Fett Pfeil anonyme Funktionen ohne Körper? Wie werden sie mit einer solchen partiellen Anwendung bezeichnet?

Ich vermisse etwas hier, kann jemand erklären?


Update: Versuchte auf drei Browser, Chrome 50.0.2661.86, Safari 9.1 (50.0.2661.86), Firefox 44.0.2, führen alle ohne Fehler.

ESFiddle führt es auch ohne Fehler aus.

Kommentatoren Bericht Babel führt auch ohne Fehler aus.

Die Quelle der Frage ist von http://tddbin.com/#?kata=es6/language/generator/send-function, die zweite Kata.

+1

Ihr Codebeispiel läuft nicht für mich. 'Uncaught TypeError: (Zwischenwert) ist keine Funktion' –

+0

' yield' gibt zurück, was immer Sie in '.next (...)' übergeben. Du hast nur Glück, dass du nur '.next()' 2 mal aufgerufen hast, es würde das nächste Mal werfen. – Bergi

+0

@Ben: Ja, aber dann stellt sich die Frage ... Was hat Sie dazu gebracht zu glauben, dass dieser Code überhaupt gültig war? Hast du es irgendwo gesehen? –

Antwort

4

I'm not sure how this works.

äh, ja, es sollte nicht funktionieren. Es funktioniert nur wegen eines Fehlers in Babel.

yield doesn't return a function reference, so what are the parenthetical statements like (yield 2) doing - are they fat arrow anonymous functions without bodies? How are they called using partial application like that?

Nein, es ist wirklich nur Standardfunktion Anwendung, keine Magie. yieldkönnte eine Funktionsreferenz zurückgeben, und wenn dies der Fall ist, könnte dies funktionieren. Wenn dies nicht der Fall ist, wird beim dritten Aufruf eine Ausnahme ausgelöst.

Als Beispiel für eine funktionierende Version:

function* generatorFunction() { 
    yield (yield 1)(yield 2)(yield 3)(); 
} 
var test = (a) => { 
    console.log(a); 
    return (b) => { 
    console.log(b); 
    return (c) => { 
     console.log(c); 
     return 4; 
    }; 
    }; 
}; 
var iterator = generatorFunction(); 
iterator.next(); // {value: 1, done: false} 
iterator.next(test); // {value: 2, done: false} 
iterator.next("a"); // "a" {value: 3, done: false} 
iterator.next("b"); // "b" undefined {value: 4, done: false} 
iterator.next("d"); // {value: undefined, done: true} 

Wie funktionierts? Diese verschachtelte/gekettet yield Aussagen sollten besser geschrieben werden als

function* generatorFunction() { 
    let fn1 = yield 1; 
    let a = yield 2; 
    let fn2 = fn1(a); 
    let b = yield 3; 
    let fn3 = fn2(b); 
    let res = fn3(); 
    let d = yield res; 
    return undefined; 
} 

Commenters report Babel executes without errors as well.

, die aufgrund eines babel Fehler ist. Wenn Sie die transpiler output überprüfen, verhält es sich tatsächlich wie

function* generatorFunction() { 
    let fn1 = yield 1; 
    let a = yield 2; 
    let b = yield 3; 
    // these are no more executed with only 3 `next` calls 
    let fn2 = fn1(a); 
    let fn3 = fn2(b); 
    let res = fn3(); 
    let d = yield res; 
    return undefined; 
} 
+0

Möchte jemand diesen Fehler melden? – Bergi

+2

Abgelegt in ['Regenerator'] (https://github.com/facebook/regenerator/issues/244) und in [' Babel'] (https://phabricator.babeljs.io/T7327). Danke, dass du das aufgespürt hast. – loganfsmyth