I'd like to have a function like this:
export async function* iterateDir(dir: string) {
let list = await fs.readdir(dir); // fs-promise implementation of readdir
for (let file of list) {
yield file;
}
}
Which I would use like:
for (let file in iterateDir(dir)) {
processFile(file);
}
This doesn't work because a function cannot be both async and a generator.
How would I structure the code to achieve the same?
await fs.readdir
to callbacks, I assume the outer for..of loop would not wait.iterateDir()
will be slow.For reference: async generator function proposal
Async generator functions behave similarly to generator functions: the generator function returns an object that has a next() function, and calling next() executes the generator function until the next yield . The difference is that an async iterator's next() function returns a promise.
The syntax is simple: prepend function* with async . That makes the generator asynchronous. And then use for await (...) to iterate over it, like this: async function* generateSequence(start, end) { for (let i = start; i <= end; i++) { // Wow, can use await!
Async - Await has been supported by TypeScript since version 1.7. Asynchronous functions are prefixed with the async keyword; await suspends the execution until an asynchronous function return promise is fulfilled and unwraps the value from the Promise returned.
It's explained in detail here: " IterableIterator is an interface defined by TypeScript that combines the contracts of Iterables and Iterator into one. This is because, in some cases, it makes sense to have the Iterable as an Iterator itself, removing the need to have an external class that serves as the iterator."
This is supported in TypeScript 2.3 - tracked issue
It introduces a few new types, notably:
interface AsyncIterable<T> {
[Symbol.asyncIterator](): AsyncIterator<T>;
}
but most importantly it also introduces for await ... of
for await (const line of readLines(filePath)) {
console.log(line);
}
where
async function* readLines(path) {
//await and yield ...
}
Be aware that if you want to try this you will need to configure typescript to let it know you have run-time support (add "esnext.asynciterable" to lib
list) you will probably need to polyfill Symbol.asyncIterator
. see TS2318: Cannot find global type 'AsyncIterableIterator' - async generator
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With