为什么这个 async/Promise 方法同步运行?

Why is this async/Promise method running synchronously?

提问人:JohnTortugo 提问时间:8/1/2023 更新时间:8/1/2023 访问量:39

问:

我真的是 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.

JavaScript 节点 .js XML 解析

评论

0赞 Mr. Polywhirl 8/1/2023
你从来没有在你的?res()setTimeout
0赞 Mr. Polywhirl 8/1/2023
为了解析 a,您需要调用 , aka (第一个回调参数)。Promiseres()resolve()
0赞 JohnTortugo 8/1/2023
喜欢这个:async function saveObj(data, cnt) { return new Promise(res => { setTimeout(() => { let jObj = parser.parse(data); console.log("Parsed content number " + cnt); }, 1000); res(); }); }
0赞 Mr. Polywhirl 8/1/2023
这看起来是正确的。我在下面添加了一个回复。
0赞 Keith 8/1/2023
let jObj = parser.parse(data);哦,等一下,你是说XML那么大,这需要很长时间。是的,这是一个典型的例子,Node worker 线程开始发挥作用 -> nodejs.org/api/worker_threads.html.parse(data)

答:

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