【发布时间】:2018-04-12 11:30:11
【问题描述】:
已经阅读了大量的文章和文档,但是这个主题对我来说仍然不够清楚。引用一个答案https://stackoverflow.com/a/46004461/630169:
只要 async/await 中包含的代码是非阻塞的 它不会阻塞,例如,数据库调用、网络调用、文件系统调用。
但是如果包含在 async/await 中的代码是阻塞的,那么它会 阻塞整个 Node.js 进程,例如无限循环、CPU 图像处理等密集型任务。
但是,Understanding the node.js event loop 说:
当然,后端有DB的线程和进程 访问和进程执行。
在 C# 中,编写标记为 async 的函数并使用 await 调用就足够了,因此 .Net 将其放在另一个线程中。然而,它让我感到困惑的是,在 Node.js 中以不同方式组织的东西,async/await 函数仍然会阻塞主线程。
所以问题是:如何在 node.js 中编写(组织)任意async/await 函数以确保它将在单独的线程或进程中异步运行?有好的代码示例吗?一些npm 模块?让它没有比 C# 变体更棘手也很好。谢谢!
一些使其成为非阻塞的函数示例,例如,如果我想要同步 DB 调用来实现异步(非阻塞):
var Database = require('better-sqlite3');
var db = new Database('./my_db.sqlite');
async function DBRequest() {
var row = db.prepare("SELECT * FROM table");
return row;
};
注意: better-sqlite3 — 同步模块。
【问题讨论】:
-
“在 C# 中,编写标记为 async 的函数并使用 await 调用就足够了,因此 .Net 将其放在另一个线程中。”。这不是 async/await 的工作方式,这是您的基本误解 - 异步和线程是不同的概念,虽然 可能 使用 async/await 等待后台线程,但 不是 主要用例。
-
node.js 是单线程的。您可以编写长时间运行的阻塞代码,这样它就可以为其他函数产生执行时间——肯定有这样的技术——但阻塞代码就是阻塞代码。
-
@TKoL 需要很好的例子来制作阻塞代码 - 非阻塞。
-
我不会给你一个具体的例子,但我可以向你解释如何去做。假设您要处理一个包含 100 个项目的数组,每个项目将花费 0.5 秒(阻塞时间)来处理——您想编写一个函数来处理它们,但您不希望它阻塞 50 秒。你要做的是编写你的函数来处理数组的一个元素,然后编写一个递归函数来在
setTimeout延迟后处理数组中的下一项。这是一种技术。 -
@TKoL 不适用于所有情况。需要更通用的方法。例如,我有同步 DB 库调用,并想创建使用它的函数
async。
标签: javascript c# node.js multithreading async-await