javascript - 在另一个 Promise 包裹的流中等待 Promise
问题描述
我有一个包含每行路径的文本文件(可以有空格),例如
C:\Windows\system32
C:\Windows\system33
C:\Windows\DirectX.log
然后我想逐行读取这个文件并确定每行上的文件/目录是否存在。
以下代码可以正常工作:
const path = require("path");
const fs = require("fs-extra");
const readline = require("readline");
const FILE = path.join(__dirname, "file.txt");
(async () => {
const rl = readline.createInterface({
input: fs.createReadStream(FILE)
});
let lines = [];
await new Promise((resolve, reject) => {
rl.on("line", line => line && lines.push(line));
rl.on("close", () => resolve());
rl.on("error", err => reject(err));
});
for (let line of lines) {
console.log(line, await fs.pathExists(line));
}
})();
输出是:
C:\Windows\system32 true
C:\Windows\system33 false
C:\Windows\DirectX.log true
但我想知道一旦我有了路径,我怎么能检查文件/文件夹的存在,即在“线路”事件上。所以我尝试了这个:
const path = require("path");
const fs = require("fs-extra");
const readline = require("readline");
const FILE = path.join(__dirname, "file.txt");
(async () => {
const rl = readline.createInterface({
input: fs.createReadStream(FILE)
});
await new Promise((resolve, reject) => {
rl.on("line", async line => line && console.log(line, await fs.pathExists(line)));
rl.on("close", async () => {
console.log("close");
resolve();
});
rl.on("error", err => reject(err));
});
})();
结果是:
C:\Windows\system32 true
C:\Windows\system33 false
close
C:\Windows\DirectX.log true
这并不意外。但是我怎样才能确保resolve()
只有在“line”事件的所有承诺都得到解决后才被调用?
解决方案
您可以将所有“行”事件承诺推入一个数组并在“关闭”事件上使用Promise.all()
,当给定承诺数组上的所有承诺都被解决时,它会解决,或者一旦数组中的一个承诺被拒绝,就会被拒绝。
像这样的东西:
let promisesArray = [];
let resArray = await new Promise((resolve, reject) => {
rl.on("line", line => promisesArray.push(fs.pathExists(line).catch( (reason) => { /* Handle Errors */ })));
rl.on("close", async () => {
console.log("close");
return Promise.All(promisesArray);
});
rl.on("error", err => reject(err));
});
并将resArray
在 promisesArray 的同一位置保存每个 promise 的结果数组。
编辑:正如Bergi 指出的,Promise.All()
当所有的promise 都被触发时,期望被正确调用,但是在这里它们被一个“line”事件触发,这可能会导致一些延迟。因此,如果其中一个在途中被拒绝,则可能Promise.All()
尚未调用,因为“关闭”事件尚未到达,因此您将收到“未处理的承诺拒绝”错误,这会使您的程序崩溃。设置承诺时处理错误保证正确的错误处理并且没有崩溃:)
推荐阅读
- asp.net - 如何在全局范围内使用 OverrideAuthorization 来授权 MVC 中的特定角色(而不强制对整个程序进行授权)?
- python-3.x - 如何在 tkinter gui 中删除循环依赖
- c++ - 闪存卡游戏的数字添加不正确?Cpp
- java - 线程“主”java.lang.ArrayIndexOutOfBoundsException 中的异常:索引 1 超出长度 1 的范围
- python - seaborn FutureWarning:将以下变量作为关键字参数传递:x,y
- django - 在 ForeignKey Django 模型中获取显示选择
- vb.net - 如果不满足某些条件,则跳过文本文件 vb.net
- flutter - Retrofit Flutter 不生成model-json转换方法
- flurry - #flurry 仪表板是否存在最近或已知的问题?
- c++ - 将类(mixin)的功能与模棱两可的调用结合起来