Skip to content

Instantly share code, notes, and snippets.

@michaelrambeau
Last active July 6, 2018 14:48
Show Gist options
  • Save michaelrambeau/5e170008d6605df4d052b2d3acb3887d to your computer and use it in GitHub Desktop.
Save michaelrambeau/5e170008d6605df4d052b2d3acb3887d to your computer and use it in GitHub Desktop.
Async iteration with `for await` loop, an example for https://weekly.bestofjs.org/issues/5
/*
Script to run in the latest version of node.js (tested in v10.5.0)
to check the behavior of asynchronous iterators.
*/
// Return a Promise that resolves after 0.5 seconds, to simulate an API request
async function fetchUser(i) {
return new Promise(resolve => {
setTimeout(resolve, 500, `User #${i}`)
})
}
// Return an object that we can loop through using a `for loop` ("iterable")
function getUsers({ count }) {
return {
[Symbol.iterator]: function*() {
let i = 1
while (true) {
if (i > count) return // `return` to inform the consumer that there is no more data
const value = fetchUser(i)
i = i + 1
yield value // yielding a Promise, the function is "paused"
}
}
}
}
async function main() {
console.log('Start the iteration!')
const users = getUsers({ count: 5 })
for await (const user of users) {
console.log(user)
}
console.log('THE END')
}
main()
@michaelrambeau
Copy link
Author

michaelrambeau commented Jul 1, 2018

This script shows how to loop through asynchronous iterators, using the for await loop.
We created a function called getUsers() that provides a kind of "stream" of users.

In order to be able to use a for of loop, it should return an "iterable" object, that is to say an object that has a Symbol.Iterator key, providing the "iterator". The iterator is a function generator (hence the syntax function*), a function that can be paused using the yield keyword, to provide data to the consumer.

Data is consumed in the "main()" function.

If it works, it should output in the console, every 500 ms:

User1
User2
User3
User4
User5

Tested in node.js v10.5.0. It seems to work in the latest version of Firefox too (60.0.2) but not in Chrome.

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