不同的字符串,有源头和承诺



我在项目中使用了一个函数:

function readStream(file) {
console.log("starte lesen");
const readStream = fs.createReadStream(file);
readStream.setEncoding('utf8');
return new Promise((resolve, reject) => {
let data = "";
readStream.on("data", chunk => data += chunk);
readStream.on("end", () => {resolve(data);});
readStream.on("error", error => reject(error));
});
}

它将读取一个大约有800行的xml文件

readStream.on("end", () => {console.log(data); resolve(data);});

然后xml数据就完成了。一切都很好。但如果我现在从另一个函数调用这个readStream

const dpath = path.resolve(__basedir, 'tests/downloads', 'test.xml');
let xml = await readStream(dpath);
console.log(xml);

则剪切XML数据。我觉得800行没什么大不了的。那么,如果数据在这个位置被剪切,而不是在函数本身中,会发生什么呢。

我试过如下方式,它似乎对我有效。

对于完整的运行示例,克隆node-chake-xmlstreamer并运行node main.js

xmlstreamer.js

const fs = require('fs');
module.exports.readStream = function (file) {
console.log("read stream started");
const readStream = fs.createReadStream(file);
readStream.setEncoding('utf8');
return new Promise((resolve, reject) => {
let data = "";
readStream.on("data", chunk => data += chunk);
readStream.on("end", () => {console.log(data); resolve(data);});
readStream.on("error", error => reject(error));
});
}

main.js

const path = require('path');
const _streamer = require('./xml-streamer');
async function main() {
const xml = await _streamer.readStream( path.resolve(__dirname, 'files', 'test.xml'));
console.log(xml);
}
main();

p.S.在上面提到的节点中,欺骗测试xml文件有11121行。

有时同步+异步代码在同一时间调用时会得到竞争条件。请尝试在事件处理程序上使用setImmediate(resolve, data),它将在下一个进程刻度上解决。

或者,如果你的目标是节点v12或更高版本,你可以使用流异步迭代器接口,这对你的代码来说会更干净:

async function readStream(file) {
console.log("starte lesen");
const readStream = fs.createReadStream(file);
readStream.setEncoding('utf8');
let data = "";
for await (const chunk of readStream) {
out += chunk;
}
return out;
}

如果您碰巧使用现代版本的节点,则有fs.promises

const { promises: fs } = require('fs')
;(async function main() {
console.log(await fs.readFile('./input.txt', 'utf-8'));
})()

最新更新