Created
June 3, 2020 20:49
-
-
Save kendru/70a0a5736b7214b4261fee167817f0aa to your computer and use it in GitHub Desktop.
Example of converting a recursive callback to an asynchronous iterator
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
const promise_ = Symbol('promise'); | |
class Deferred { | |
constructor() { | |
this[promise_] = new Promise((resolve, reject) => { | |
this.resolve = resolve; | |
this.reject = reject; | |
}); | |
} | |
get promise() { | |
return this[promise_]; | |
} | |
} | |
function countDown(n, cb) { | |
if (n > 0) { | |
setTimeout(() => cb([n, n], n - 1), 500); | |
} | |
} | |
async function* getResults() { | |
let nextN = null; | |
let rows = null; | |
let batchDone = new Deferred(); | |
function callback(rows_, nextN_) { | |
rows = rows_; | |
nextN = nextN_; | |
batchDone.resolve(); | |
} | |
countDown(5, callback); | |
while (true) { | |
await batchDone.promise; | |
for (const row of rows) { | |
yield row; | |
} | |
if (!nextN) { | |
return; | |
} | |
countDown(nextN, callback); | |
nextN = null; | |
rows = null; | |
batchDone = new Deferred(); | |
} | |
} | |
async function main() { | |
for await (const row of getResults()) { | |
console.log('Got row', row); | |
} | |
} | |
main(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment