【问题标题】:Is it possible to write "real" async functions in node.js [duplicate]是否可以在 node.js 中编写“真正的”异步函数 [重复]
【发布时间】:2021-04-04 20:42:15
【问题描述】:

我一直在尝试了解 async/await 关键字和 Promise 在 NodeJs 中是如何工作的。下面是我的测试代码:

function lowLevelFileReading() {
    for (let i = 0; i < 100000; i++) {
        for (j = 0; j < 100000; j++) {
            let lol = 5;
            lol = lol * lol + 2;
        }
    }
}

function slowPromise() {
    return new Promise(resolve => {
        setTimeout(() => {
            console.log("starting slow promise " + new Date())
            lowLevelFileReading();
            resolve("slow");
            console.log("slow promise is done " + new Date())
        }, 1000);
    })
}

function fastPromise() {
    return new Promise(resolve => {
        setTimeout(() => {
            console.log("starting fast promise" + new Date())
            resolve("fast")
            console.log("fast promise is done" + new Date())
        }, 3000);
    })
}

async function parallel() {
    // Start 2 "jobs" in parallel and wait for both of them to complete
    await Promise.all([
        (async()=>console.log(await slowPromise()))(),
        (async()=>console.log(await fastPromise()))()
    ])
}

parallel();

这是我的控制台输出:

starting slow promise Sun Apr 04 2021 10:41:30 GMT+0300 (GMT+03:00)
slow promise is done Sun Apr 04 2021 10:41:54 GMT+0300 (GMT+03:00)
slow
starting fast promiseSun Apr 04 2021 10:41:54 GMT+0300 (GMT+03:00)
fast promise is doneSun Apr 04 2021 10:41:54 GMT+0300 (GMT+03:00)
fast

在我的电脑中,lowLevelFileReading() 大约需要 25 秒才能完成,所以我认为它适合测试一些长时间运行的操作。

如上图所示,slowPromise() 中的代码设置为 1 秒后启动,fastPromise() 中的代码设置为 3 秒后启动。

我预计快速承诺会在慢速承诺后 2 秒开始。但它没有发生。您可以在控制台输出中看到,在慢速承诺完全完成之前,快速承诺不会启动。请查看控制台日志的时间戳。

我认为用 javascript 做我想做的事情是不可能的。但是后来我不明白“fs”库中的异步文件读取功能是如何工作的。我的意思是,fs.readFile() 的实现和我想象中的lowLevelFileReading() 实现有什么区别。节点对某些“特殊”方法的处理方式不同吗?

我无法想象如何将 node.js 服务器用作具有数百万用户且操作耗时的网站的后端。您能否提供一些见解?

【问题讨论】:

  • Promise 可以说是并发运行的——不是并行的。 Javascript 是单线程的,lowLevelFileReading 会阻塞执行,直到它完成。如果您有一项真正需要大量计算的任务,您可能需要查看Workers

标签: javascript node.js promise


【解决方案1】:

快速免责声明:我刚读到这篇文章,我可能解释的有些错误。

问题在于 Node.js 通常运行单线程。但是当运行某种非javascript操作时,它可以“外包”它并使其在内核上并行运行。但是当你有一个像 lowLevelFileRead 这样的函数时,它不运行任何类型的 I/O 操作,它会阻止其他代码的执行。

这是我找到的一篇文章,可能有助于解释事情:

https://medium.com/@mohllal/node-js-multithreading-a5cd74958a67

【讨论】:

  • 使用您的代码版本,直到 lowLevelFileReading() 完成,快速承诺仍然不会启动。
  • 这并不能解决 lowLevelFileReading 函数缓慢且 阻塞 的问题,它只是在该缓慢的阻塞函数在解决 promise 之前运行之后增加了延迟.
  • "将其设置为超时使其异步运行。" ——不,它没有。它只是让它在 3 秒后运行。它仍然缓慢且阻塞。其他东西可以它之前运行,但不能和它同时运行。
  • 但是fast promise在读取操作之前就开始了
  • 首先运行快速承诺不是重点,重点是lowLevelFileReading 会阻塞其他所有内容无论何时它都在运行。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多