admin管理员组文章数量:1178539
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?
- If I change the
await fs.readdir
to callbacks, I assume the outer for..of loop would not wait. - If I get rid of the generator and the directory is huge,
iterateDir()
will be slow.
For reference: async generator function proposal
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?
- If I change the
await fs.readdir
to callbacks, I assume the outer for..of loop would not wait. - If I get rid of the generator and the directory is huge,
iterateDir()
will be slow.
For reference: async generator function proposal
Share Improve this question edited Nov 3, 2016 at 16:43 Borek Bernard asked Nov 3, 2016 at 16:05 Borek BernardBorek Bernard 53.2k62 gold badges176 silver badges246 bronze badges 7 | Show 2 more comments2 Answers
Reset to default 38This 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
Stream of future values is called Observable
. So the most natural thing is to use a library like RxJS or most.js. If you don't want to introduce a new complex library only to use it once, use the good old approach with callbacks:
const path = require("path");
const fs = require("mz/fs");
async function listDirectory(dirName, cb, level = 0) {
for (let fileName of await fs.readdir(dirName)) {
let absName = path.resolve(dirName, fileName);
let isDirectory = (await fs.stat(absName)).isDirectory();
cb({ level, fileName });
if (isDirectory) {
await listDirectory(absName, cb, level + 1);
}
}
}
listDirectory(".", ({ level, fileName }) => {
console.log(" ".repeat(level) + fileName);
});
If you try to convert the callback to some better abstraction, you will rediscover RxJS sooner or later. It's similar to converting one-shot callbacks to promises.
本文标签: javascriptTypeScript async generatorStack Overflow
版权声明:本文标题:javascript - TypeScript: async generator - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1738107247a2064406.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
iterateDir
would be recursive. For everyfile
, there would be a detection whether it's a directory or not, and if it is, calliterateDir
recursively. In which case I don't know how to split the async and generation functionality. Which is the point of the question.. – Borek Bernard Commented Nov 3, 2016 at 16:41