我是 Node.js 库的作者,我想使用Async Hooks来改进 DX。但我担心性能。
我读过一些故事说一切都很好,也有一些故事说性能是一个障碍。
从理论上讲,异步应该只发生在 IO 操作中,性能惩罚应该几乎是 ~0。(因为 IO 操作比运行 JS 代码要贵几个数量级。)
但是,实际上,在每个异步调用上运行额外的 JS 是否会导致不可忽略的性能下降?
您对异步钩子的性能有何经验?
用例
具体用例是Wildcard API,我在其中使用 Async Hooks,它为 Wildcard 用户提供了出色的人体工程学:
const { server } = require("@wildcard-api/server");
const { context } = require("@wildcard-api/context");
const db = require("./path/to/db");
// Server endpoint for user login
server.login = async (userEmail, password) => {
if (!checkCredentials(userEmail, password)) {
return { wrongCredentials: true };
}
const { userId, userName } = await db.getUser(userEmail);
// Context modifications are persisted. (Under the hood,
// Wildcard uses Cookies to persist the context.)
context.user = {
userId,
userName,
};
};
// Server endpoint to get the to-do list of the logged-in user.
server.getTodoList = async () => {
// `context.userId` is available here!
const { userId } = context;
if (!userId) {
return { notLoggedIn: true };
}
const todos = await db.getTodoList(userId);
return todos;
};
// The neat thing here is that the following also works:
<div>
{/* ... */}
{/* Somewhere deep in a React tree... */}
{/* ... */}
<Header>
{
// The Wildcard `context` is availble here!
// Thanks to async hooks, Wildcard knows to which
// HTTP request `context` belongs too. (While doing SSR.)
context.userId ? <SignIn /> : <Logout />
}
</Header>;
</div>;
感谢 Async Hooks,通配符context
在 HTTP 请求的生命周期内的任何地方都可用(!)。
通配符的异步钩子代码很小,但会针对在 HTTP 请求上下文中发生的每个异步调用运行。
这里的主要危险是内存泄漏,但 Wildcard 的测试套件正在检查是否存在内存泄漏。