Node.js 使用 async/await 读取文件
Posted
技术标签:
【中文标题】Node.js 使用 async/await 读取文件【英文标题】:Node.js read file using async/await 【发布时间】:2019-05-30 18:31:53 【问题描述】:我正在尝试使用异步/等待代码来读取文件。 这是我的代码:
var fs = require('fs');
function readFile(fileName)
return new Promise(resolve =>
//console.log(test);
fs.readFile(fileName, 'utf8', function (err, data)
if (err) throw err;
console.log(fileName)
console.log(data)
)
resolve();
);
async function run()
await readFile('file1.txt');
await readFile('file2.txt');
readFile('file3.txt');
run();
但结果仍然是随机的。这意味着 file3 有时会在 file2 之前读取。我哪里做错了?
【问题讨论】:
您将resolve
置于异步调用之外,因此它会立即得到解决。
How do I convert an existing callback API to promises?的可能重复
这能回答你的问题吗? Using filesystem in node.js with async / await
【参考方案1】:
有很多方法可以实现。
大部分在this link中都有解释
我会写一个简单的:
1) 使用util.promisify
将回调方法转换为promise:
const fs = require('fs');
const util = require('util');
const readFile = (fileName) => util.promisify(fs.readFile)(fileName, 'utf8');
(async () =>
try
const files = ['file1.txt', 'file2.txt', 'file3.txt'];
for (const file of files)
console.log(
await readFile(file)
);
catch (error)
console.error(error);
)();
2) *Sync
方法。由于您的代码不处理并发您可以使用*Sync
方法:
const fs = require('fs');
try
const files = ['file1.txt', 'file2.txt', 'file3.txt'];
for (const file of files)
console.log(
fs.readFileSync(file, 'utf8')
);
catch (error)
console.error(error);
顺便说一句。这是您的固定代码:
var fs = require('fs');
function readFile(fileName)
return new Promise((resolve, reject) =>
fs.readFile(fileName, 'utf8', function (error, data)
if (error) return reject(error);
console.log(fileName)
console.log(data)
resolve();
)
);
async function run()
await readFile('file1.txt');
await readFile('file2.txt');
await readFile('file3.txt');
run();
因为您正在调用 readFile 并以相同的异步序列解析它,所以它同时被调用,这是 race condition
的原因。
您必须等待回调处理然后解决它(在回调范围内)。
【讨论】:
感谢您展示其他方法来实现我的目标...实际上还有一些额外的代码来处理数据。是的,代码通过将 resolve() 移动到 fs.readFile() 内部来工作。备选方案 2 更容易理解。【参考方案2】:本机节点功能有几个选项
A) 使用fs.promises
API
您可以在导入别名fs.promises
时使用destructuring assignment,就像fs
一样
const promises: fs = require("fs");
(async () =>
try
let file1 = await fs.readFile("file1.txt", "utf-8");
let file2 = await fs.readFile("file2.txt", "utf-8");
catch (e)
console.log("e", e);
)()
B) 与util.promisify
API
const fsSync = require("fs");
const promisify = require("util")
const fs =
readdir: promisify(fsSync.readdir),
readFile: promisify(fsSync.readFile),
// etc
;
(async () =>
try
let file1 = await fs.readFile("file1.txt", "utf-8");
let file2 = await fs.readFile("file2.txt", "utf-8");
catch (e)
console.log("e", e);
)()
进一步阅读
How to read file with async/await properly? Using filesystem in node.js with async / await【讨论】:
以上是关于Node.js 使用 async/await 读取文件的主要内容,如果未能解决你的问题,请参考以下文章
node.js async/await 与 MySQL 一起使用
在 Node.js 中使用 async/await 正确处理错误
Node.js 7 的 async await 终于来了,不过怎么觉得没啥用
在node.js中使用带有async / await的文件系统
使用 Javascript(以及 Node.js)使用 async/await 和 Promises 的正确方法是啥 [重复]