Last active
September 21, 2022 10:46
-
-
Save domenic/60664d6659072b323685 to your computer and use it in GitHub Desktop.
Push vs. pull async generators
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
async function* foo() { | |
console.log("1"); | |
await Q.delay(1000); | |
console.log("2"); | |
yield "a"; | |
console.log("3"); | |
await Q.delay(1000); | |
console.log("4"); | |
yield "b"; | |
} | |
// If the return type is an "observable" (push-based), once the observable is subscribed to, | |
// the function will run at the pace that it sets (i.e. the last line will always run 2000 ms | |
// after the first line) | |
console.log("before call"); | |
var observable = foo(); | |
console.log("after call; before subscribe"); | |
foo.subscribe( | |
function onNext(value) { | |
console.log("onNext: ", value); | |
}, | |
function onComplete() { | |
console.log("onComplete"); | |
} | |
); | |
// Resulting timeline: | |
// "before call" | |
// "after call; before subscribe" | |
// "1" | |
// ... wait 1000 ms ... | |
// "2" | |
// "onNext: a" | |
// "3" | |
// ... wait 1000 ms ... | |
// "4" | |
// "onNext: b" | |
// "onComplete" | |
// If the return type is an "async generator", i.e. something with { next, throw } | |
// methods where next returns a promise, then the async generator function can be suspended | |
// at the whim of the consumer (just like normal sync generator functions). In this example, | |
// we make the last line of the async generator function run 4000 ms after the first line. | |
console.log("before call"); | |
var ag = foo(); | |
console.log("after call; before next"); | |
ag.next().then(v => console.log("next1: ", v)); | |
// Consumer can choose not to execute function body until later: | |
Q.delay(2000).then(() => { | |
ag.next().then(v => console.log("next2: ", v)); | |
ag.next().then(v => console.log("next3: ", v)); | |
}); | |
// Resulting timeline: | |
// "before call" | |
// "after call; before next" | |
// "1" | |
// ... wait 1000 ms ... | |
// "2" | |
// "next1: { value: 'a', done: false }" | |
// ... wait 2000 ms ... | |
// "3" | |
// ... wait 1000 ms ... | |
// "4" | |
// "next2: { value: 'b', done: false }" | |
// "next3: { value: undefined, done: true }" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
if next() returns a promise, won't you have to "await" on lines 51, 56-57, to get that ordering? i would otherwise expect the delay(2000) to be concurrent with the generator pausing.