Skip to content

Instantly share code, notes, and snippets.

@domenic
Last active September 21, 2022 10:46
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save domenic/60664d6659072b323685 to your computer and use it in GitHub Desktop.
Save domenic/60664d6659072b323685 to your computer and use it in GitHub Desktop.
Push vs. pull async generators
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 }"
@robey
Copy link

robey commented Jun 7, 2014

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.

Copy link

ghost commented Sep 21, 2022

what is Q ? thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment