Last active
October 28, 2015 23:49
-
-
Save alanthai/8be3c8548722d1f902ac to your computer and use it in GitHub Desktop.
Async using Generators and Promises
This file contains hidden or 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
/** ES 2015 naive implementation of https://github.com/tj/co */ | |
function coAsync(generator) { | |
var gen = generator(); | |
return new Promise(function(resolve, reject) { | |
(function async({value, done}) { | |
if (done) return resolve(value); | |
if (Array.isArray(value)) { | |
Promise.all(value).then(values => async(gen.next(values))); | |
} else { | |
value.then(_value => async(gen.next(_value))); | |
} | |
})(gen.next()); | |
}); | |
} | |
function coAsyncWrap(generator) { | |
return value => coAsync(generator.bind(null, value)); | |
} | |
// example usage | |
function waitThenReturn(value, seconds=1) { | |
return new Promise((resolve, reject) => { | |
setTimeout(() => resolve(value), seconds * 1000); | |
}); | |
} | |
coAsync(function*() { | |
console.log('coAsync'); | |
// waits 1 second, then returns value 1 | |
let a1 = yield waitThenReturn(1); | |
console.log(a1); | |
let a2 = yield waitThenReturn(2); | |
console.log(a2); | |
let a3 = yield waitThenReturn(3); | |
console.log(a3); | |
return [a1, a2, a3]; | |
}) | |
.then(([b1, b2, b3]) => { | |
console.log(b1, b2, b3); | |
return fn(3); | |
}) | |
.then(([b1, b2, b3]) => { | |
console.log(b1, b2, b3); | |
return fn2(4); | |
}) | |
.then(([b1, b2, b3]) => { | |
console.log(b1, b2, b3); | |
}); | |
// same as above but allows you to feed a value to the generator | |
var fn = coAsyncWrap(function*(value) { | |
console.log('coAsyncWrap with value', value); | |
let a1 = yield waitThenReturn(value + 1); | |
console.log(a1); | |
let a2 = yield waitThenReturn(2); | |
console.log(a2); | |
let a3 = yield waitThenReturn(3); | |
console.log(a3); | |
return [a1, a2, a3]; | |
}); | |
// can return all yielded values at once; | |
var fn2 = coAsyncWrap(function*(value) { | |
console.log('coAsyncWrap 2 with value', value); | |
return yield [ | |
waitThenReturn(value + 1), | |
waitThenReturn(value + 2), | |
waitThenReturn(value + 3), | |
] | |
}); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment