ECMA6 generators: yield promise

As I understand it ECMA6 generators are supposed to be able to yield to a function that returns a promise, eventually returning the resolved/rejected.

No, that’s not their purpose. ES6 generators are supposed to provide a simple way for writing iterators – each call to a generator function produces an iterator. An iterator is just a sequence of values – like an array, but consumed dynamically and produced lazily.

Now, generators can be abused for asynchronous control flow, by producing a sequence of promises that is consumed asynchronously and advancing the iterator with the results of each awaited promise. See here for an explanation without promises.

So what your code is missing is the consumer that actually waits for the promises and advances your generator. Usually you’d use a dedicated library (like co or task.js), or one of the helper functions that many promise libraries provide (Q, Bluebird, when, …), but for the purposes of this answer I’ll show a simplified one:

function run(gf) {
    let g = gf();
    return Promise.resolve(function step(v) {
         var res = g.next(v);
         if (res.done) return res.value;
         return res.value.then(step);
    }());
}

Now with this function you can actually “execute” your getPromise generator:

run(getPromise).then(console.log, console.error);

Leave a Comment