Skip to content

Instantly share code, notes, and snippets.

@bitfishxyz
Created May 4, 2020 08:31
Show Gist options
  • Save bitfishxyz/1367a3e9134a6bcf04730b045acee466 to your computer and use it in GitHub Desktop.
Save bitfishxyz/1367a3e9134a6bcf04730b045acee466 to your computer and use it in GitHub Desktop.
function asyncToGenerator(generatorFunc) {
// A new function is returned
return function() {
// First call the generator function to generate the iterator
// Corresponding to: var gen = testG()
const gen = generatorFunc.apply(this, arguments)
// return a promise object
return new Promise((resolve, reject) => {
// Internally, a step function is defined to step over the yield barrier
// The key has two values, `next` and `throw`, which correspond to gen's next and throw methods respectively
// The arg parameter is used to give the value returned by promise.resolve() to the next yield
function step(key, arg) {
let generatorResult
// This method needs to be wrapped in a try-catch
// If an exception is thrown, reject the promise, and the error is picked up externally by a catch block.
try {
generatorResult = gen[key](arg)
} catch (error) {
return reject(error)
}
// The result of gen.next() is a {value, done} structure object
const { value, done } = generatorResult
if (done) {
// If it's already done, simply resolve the promise
// This done will only be true after the last call to the next function
return resolve(value)
} else {
// gen.next() should be called every time except at the last step
return Promise.resolve(
// This value corresponds to a promise after the yield
value
).then(
// When the promise value is resolved, it executes next function
function onResolve(val) {
step("next", val)
},
// If the promise is rejected, then we enter the step function again
// The difference is that this time the try-catch calls gen.throw(err)
function onReject(err) {
step("throw", err)
},
)
}
}
step("next")
})
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment