提问人:JohnTortugo 提问时间:8/1/2023 更新时间:8/1/2023 访问量:39
为什么这个 async/Promise 方法同步运行?
Why is this async/Promise method running synchronously?
问:
我真的是 JavaScript 的菜鸟,我正在尝试编写一个小型 ElectronJS/NodeJS 应用程序。我认为应用程序的目的与问题无关,只需说应用程序将侦听将发送~100MB的XML内容的TCP连接,然后将对解析的XML进行一些进一步的处理。由于XML内容“很大”,因此解析需要一些时间来处理,因此我决定将解析放在异步函数中,但代码显然是同步运行的。我不确定我是否做错了什么,或者仅仅是因为 JavaScript 的单线程 (AFAIU) 性质。
var net = require('net');
const fs = require('fs');
const { XMLParser, XMLBuilder, XMLValidator} = require("fast-xml-parser");
const parser = new XMLParser();
var file_counter = 0;
var server = net.createServer(function(connection) {
console.log('Client Connected');
var content = "";
connection.on('data', function(data) {
content += data.toString();
});
connection.on('end', async function() {
console.log("client " + file_counter + " disconnected");
saveObj(content, file_counter);
console.log("returned from " + file_counter);
file_counter++;
});
connection.write('y');
});
async function saveObj(data, cnt) {
return new Promise(res => setTimeout(() => {
let jObj = parser.parse(data);
console.log("Parsed content number " + cnt);
}, 1000));
}
我始终得到的输出是,即使“数据”的大小从一个连接到另一个连接有很大不同。Parsed content number 0, 1, 2...N.
答:
0赞
Mr. Polywhirl
8/1/2023
#1
确保您在回调结束时解析 promise。setTimeout
async function saveObj(data, cnt) {
return new Promise((resolve, reject) => {
setTimeout(() => {
const jObj = parser.parse(data); // This should be sync
console.log("Parsed content number " + cnt); // Also sync
resolve(); // Resolve the promise
}, 1000)
});
}
另外,请确保在调用它时:await
await saveObj(content, file_counter);
评论
0赞
JohnTortugo
8/1/2023
它似乎仍然是同步的。我会继续测试,如果我得出结论它是异步的,我会将您的答案标记为已接受。谢谢
0赞
Keith
8/1/2023
我相信他的 -> 是瓶颈,而且确实会是,坚持承诺在这里无济于事。OP 将希望使用工作线程来阻止他的主线程阻塞。parser.parse(data);
sync
评论
res()
setTimeout
Promise
res()
resolve()
async function saveObj(data, cnt) { return new Promise(res => { setTimeout(() => { let jObj = parser.parse(data); console.log("Parsed content number " + cnt); }, 1000); res(); }); }
let jObj = parser.parse(data);
哦,等一下,你是说XML那么大,这需要很长时间。是的,这是一个典型的例子,Node worker 线程开始发挥作用 -> nodejs.org/api/worker_threads.html.parse(data)