node.js 异步_Node.js v14中的异步本地存储是什么?

node.js 异步

Node.js 14 is out now, and with that release, it brings in Async Local Storage support. Now you might thing, "Meh, okay. Local storage has been around for awhile," but this time, it's different.

Node.js 14现在已经发布,在该版本中,它引入了异步本地存储支持。 现在您可能会说:“嗯,好吧。本地存储已经存在了一段时间,”但是这次有所不同。

For starters, this is the Node runtime we're talking about and not the browser. Thus, having a "localStorage" browser-like concept doesn't really make sense for Node. And the fact is, it is not the localStorage you're probably thinking of either. So what is it then?

首先,这是我们正在讨论的Node运行时,而不是浏览器。 因此,拥有像浏览器一样的“ localStorage”概念对Node而言并没有任何意义。 事实是,这也不是您可能要考虑的localStorage。 那是什么呢?

引入异步本地存储–用于异步任务的存储 (Introducing Async Local Storage – Storage for asynchronous tasks)

Consider a web server like Apache running PHP for hosting a website. When PHP receives a request from a client, your web server makes sure to spin off a new thread. It lets that thread manage all the resources, local variables, function call stack, and so on for that particular request. Simple and easy. But a problem arises with JavaScript.

考虑像Apache这样的Web服务器,该服务器运行PHP以托管网站。 当PHP接收到来自客户端的请求时,您的Web服务器将确保剥离新线程。 它使该线程可以管理该特定请求的所有资源,局部变量,函数调用堆栈等。 简单容易。 但是JavaScript会出现问题。

JavaScript is single threaded – that means you cannot have multiple threads of JS running together under a same parent process. But don't let that fool you – JS is as fast (even faster) as mature solutions like a Java backend in handling web server requests.

JavaScript是单线程的–这意味着您不能在同一父进程下同时运行JS的多个线程。 但是,请不要让您愚弄–在处理Web服务器请求时,JS与Java后端这样的成熟解决方案一样快(甚至更快)。

How does that happen? Well, that's something for another article. But the important thing here is that Node is single threaded, so you do not have the benefits of thread local storage. Thread local storage is nothing but variables and functions local to a particular thread - in our case, for handling a particular user on the webpage.

怎么发生的? 好吧,这是另一篇文章。 但是这里重要的是Node是单线程的 ,因此您没有线程本地存储的好处。 线程本地存储只不过是特定线程本地的变量和函数-在我们的例子中,是用于处理网页上的特定用户的。

为什么单线程有问题? (Why is single thread a problem?)

Single thread is a problem in this case as Node keeps executing synchronous code in one go as long as it doesn't exhaust all synchronous operations in the event loop. Then it'll keep a check on events and callbacks and execute that code whenever necessary.

在这种情况下,单线程是一个问题,因为Node会一劳永逸地执行同步代码,只要它不会在事件循环中耗尽所有同步操作即可。 然后它将检查事件和回调,并在必要时执行该代码。

In Node, a simple HTTP request is nothing but an event fired by the http library to the node to handle the request – hence it is asynchronous.

在Node中,一个简单的HTTP请求不过是http库向该节点触发以处理该请求的事件-因此它是异步的。

Now let's say you want to associate some data with this asynchronous operation. How would you do that?

现在,假设您要将一些数据与此异步操作相关联。 你会怎么做?

Well, you can create some sort of "global" variable and assign your special data to it. Then, when another request comes from the same user, you can use the global variable to read whatever you had stored earlier.

好了,您可以创建某种“全局”变量,并为其分配特殊数据。 然后,当同一用户发出另一个请求时,您可以使用全局变量读取之前存储的内容。

But it would fail spectacularly when you have more than one request on hand as Node would not execute asynchronous code serially (of course, that's the definition of asynchronous!).

但是当您手头有多个请求时,它将失败,因为Node不会串行执行异步代码(当然,这就是异步的定义!)。

Let's consider this dummy code (assume Node runtime):

让我们考虑一下这个伪代码(假设Node运行时):

server.listen(1337).on('request', (req) => {
  // some synchronous operation (save state)
  // some asynchronous operation
  // some asynchronous operation
})

Consider this sequence of events:

考虑以下事件序列:

  1. User 1 hits the server on port 1337

    用户1在端口1337上击中服务器
  2. Node starts running the synchronous operation code

    节点开始运行同步操作代码
  3. While node was running that synchronous code, another User 2 hits the server.

    当节点运行该同步代码时,另一个用户2击中服务器。
  4. Node would keep on executing the synchronous code, meanwhile the request to process the second HTTP request is waiting in the task queue.

    节点将继续执行同步代码,与此同时,处理第二个HTTP请求的请求正在任务队列中等待。
  5. When Node finishes the synchronous operation and comes to the asynchronous operation, it throws it off in the task queue and then starts processing the first task sitting in the task queue – the second HTTP request.

    当Node完成同步操作并进入异步操作时,它会将其丢弃到任务队列中,然后开始处理位于任务队列中的第一个任务–第二个HTTP请求。
  6. This time it's running that synchronous piece of code, but on the behalf of User 2's request. When that synchronous code for User 2 is done, it resumes the asynchronous execution of User 1, and so on.

    这次它正在运行该同步代码段,但是代表用户2的请求。 完成用户2的同步代码后,它将恢复用户1的异步执行,依此类推。

Now what if you want to persist specific data with that specific user whenever the asynchronous code specific to them is being called? Here's when you use AsyncStorage – storage for asynchronous flows in Node.

现在,如果您希望在调用特定于他们的异步代码时与该特定用户保持特定数据怎么办? 这是使用AsyncStorage的时候–在Node中存储异步流。

Consider this example straight from the official docs:

直接从官方文档考虑以下示例:

const http = require('http');
const { AsyncLocalStorage } = require('async_hooks');

const asyncLocalStorage = new AsyncLocalStorage();

function logWithId(msg) {
  const id = asyncLocalStorage.getStore();
  console.log(`${id !== undefined ? id : '-'}:`, msg);
}

let idSeq = 0;
http.createServer((req, res) => {
  asyncLocalStorage.run(idSeq++, () => {
    logWithId('start');
    // Imagine any chain of async operations here
    setImmediate(() => {
      logWithId('finish');
      res.end();
    });
  });
}).listen(8080);

http.get('http://localhost:8080');
http.get('http://localhost:8080');
// Prints:
//   0: start
//   1: start
//   0: finish
//   1: finish

This example is showing nothing but the "stickyness" of the idSeq with the respective request. You can imagine how express populates the req.session object with the correct user every time. In a similar fashion, this is a low level API using a lower level construct in Node called async_hooks which is still experimental, but is pretty cool to know!

此示例仅显示idSeq与相应请求的“粘性”。 您可以想象每次express如何用正确的用户填充req.session对象。 以类似的方式,这是一个低级API,它在Node中使用了一个较低级的结构async_hooks ,该结构仍处于试验阶段,但知道起来很酷!

性能 (Performance)

Before you try to roll this out in production, beware – this is not something I would really recommend anybody do if not absolutely needed. This is because it comes with a non-negligible performance hit on your application. This is primarily because the underlying API of async_hooks is still a WIP, but the situation should improve gradually.

在尝试将其投入生产之前,请当心–如果不是绝对需要的话,我不建议任何人这样做。 这是因为它给您的应用程序带来了不可忽视的性能影响。 这主要是因为async_hooks的基础API仍然是WIP,但是这种情况应该逐渐改善。

结论 (Conclusion)

That's basically it! A very simple brief introduction to what AsyncStorage is in Node 14 and what's the high level overall idea for it. If you want to learn all about new features in Node.js, check out this video:

基本上就是这样! 一个简单的简短介绍,介绍Node 14中的AsyncStorage以及它的高层总体思路。 如果您想全面了解Node.js的新功能,请观看以下视频:

Also, if you're an early adopter, try out codedamn – a platform for developers to learn and connect. I've been rolling out some sweet features there for you to try! Stay tuned.

另外,如果您是早期采用者,请尝试Codedamn –一个供开发人员学习和联系的平台。 我一直在那里推出一些不错的功能供您尝试! 敬请关注。

Peace!

和平!

翻译自: https://www.freecodecamp.org/news/async-local-storage-nodejs/

node.js 异步

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值