Last active
January 27, 2017 10:12
-
-
Save cbrunnkvist/0f4cc3655bdcca2a0e1ea0062be45ecc to your computer and use it in GitHub Desktop.
Extensively commented version of the simplest possible ES6 `co`/`Bluebird.coroutine`-like implementation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function executeWithCoroutine(generatorFunction) { | |
function letItYield(rejectionError, resolvedValue) { | |
// 1st round: resolvedValue is empty at kick off (see last line in executeAsCoroutine) | |
// 2nd round and onwards: resolvedValue is the value we pass ourselves at promise resolution | |
// let the generatorObject deal with the error in case of promise rejection | |
if (rejectionError) { | |
generatorObject.throw(rejectionError) | |
} | |
// what we pass into next() will be what the current yield expression returns | |
// as execution resumes inside the generatorFunction | |
// NOTE: discarded on the 1st call to .next(), which instead just starts generatorFunction() | |
const iteratorResult = generatorObject.next(resolvedValue) | |
// stop recursion when the generatorFunction returned/is done | |
if (iteratorResult.done) { | |
return iteratorResult.value | |
} | |
// the magic: assuming that we pass Promises to yield, | |
// let their eventual fulfillment trigger iteration | |
return iteratorResult.value.then(value => letItYield(null, value), error => letItYield(error)) | |
} | |
const generatorObject = generatorFunction() | |
// kick things off and return the outermost promise, allowing .then(console.log) at the end just for fun | |
return letItYield() | |
} | |
executeWithCoroutine(function* () { | |
const resultOfAsyncOp1 = yield Promise.resolve('everything') | |
const resultOfAsyncOp2 = yield Promise.resolve('is fine') | |
const finalSyncResult = `${resultOfAsyncOp1} ${resultOfAsyncOp2}`.toUpperCase() | |
return finalSyncResult | |
}).then(console.log) | |
// -> EVERYTHING IS FINE |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment