gpt4 book ai didi

javascript - 在 Node.js 中编写非阻塞函数的正确方法

转载 作者:太空宇宙 更新时间:2023-11-04 02:51:55 27 4
gpt4 key购买 nike

我编写了一个返回 Promise 的简单函数,因此应该是非阻塞的(在我看来)。不幸的是,该程序看起来像是停止等待 Promise 完成。我不确定这里出了什么问题。

function longRunningFunc(val, mod) {
return new Promise((resolve, reject) => {
sum = 0;
for (var i = 0; i < 100000; i++) {
for (var j = 0; j < val; j++) {
sum += i + j % mod
}
}
resolve(sum)
})
}

console.log("before")
longRunningFunc(1000, 3).then((res) => {
console.log("Result: " + res)
})
console.log("after")

输出看起来像预期的那样:

before     // delay before printing below lines
after
Result: 5000049900000

但是程序在打印第二行和第三行之前会等待。你能解释一下首先打印“之前”和“之后”然后(一段时间后)结果的正确方法是什么?

最佳答案

将代码包装在 promise 中(就像您所做的那样)不会使其成为非阻塞。 Promise 执行器函数(您传递给 new Promise(fn) 的回调是同步调用的,并且会阻塞,这就是您在获取输出时看到延迟的原因。

事实上,没有办法创建你自己的非阻塞纯 Javascript 代码(就像你拥有的那样),除非将其放入子进程中,使用 WorkerThread,使用一些创建新 Javascript 线程的第三方库或使用新的实验性 Node.js API 进行线程。常规的node.js以阻塞和单线程的方式运行你的Javascript,无论它是否包含在promise中。

您可以使用诸如 setTimeout() 之类的东西来更改代码运行的“时间”,但无论何时运行,它仍然会阻塞(一旦它开始执行,在完成之前就无法运行其他任何东西)。 Node.js 库中的异步操作都使用某种形式的底层 native 代码,允许它们异步(或者它们只使用本身使用 native 代码实现的其他 Node.js 异步 API)。

But the program waits before printing second and third lines. Can you explain what should be the proper way to get "before" and "after" printed first and then (after some time) the result?

正如我上面所说,将事物包装在 Promise 执行器函数中并不会使它们变得异步。如果您想“改变”事物运行的时间(认为它们仍然是同步的),您可以使用 setTimeout(),但这并不能真正使任何事情成为非阻塞,它只是让它稍后运行(运行时仍然阻塞)。

所以,你可以这样做:

function longRunningFunc(val, mod) {
return new Promise((resolve, reject) => {
setTimeout(() => {
sum = 0;
for (var i = 0; i < 100000; i++) {
for (var j = 0; j < val; j++) {
sum += i + j % mod
}
}
resolve(sum)
}, 10);
})
}

这将重新安排耗时的 for 循环稍后运行,并且可能“看起来”是非阻塞的,但它实际上仍然阻塞 - 它只是稍后运行。为了使其真正非阻塞,您必须使用前面提到的技术之一将其从主 Javascript 线程中取出。

在 Node.js 中创建实际非阻塞代码的方法:

  1. 在单独的子进程中运行它,并在完成时获取异步通知。
  2. 使用新的实验 Worker Threads在 Node.js v11 中
  3. 将您自己的 native 代码插件编写到 node.js,并在实现中使用 libuv 线程或操作系统级线程(或其他操作系统级异步工具)。
  4. 构建在以前现有的异步 API 之上,并且您自己的代码不会在主线程中花费很长时间。

关于javascript - 在 Node.js 中编写非阻塞函数的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53876344/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com