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 heresetImmediate(() => {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 异步

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

  1. node windows更新_node.js 01 简介 - 产生,发展历程,优势,适用场景,实际应用

    node.js是什么 上面是来自于node.js 官网 (https://nodejs.org)的介绍.翻译过来,意思是node.js 基于JavaScript, 需要运行在Chrome V8 的 J ...

  2. 新手教程:不写JS,在MIP页中实现异步加载数据

    从需求谈起:在 MIP 页中异步加载数据 MIP(移动网页加速器) 的 加速原理 除了靠谱的 MIP-Cache CDN 加速外,最值得一提的就是组件系统.所有 JS 交互都需要使用 MIP 组件实现 ...

  3. javascript等待异步线程完成_JavaScript 中的异步原理

    来源:极链科技 作者:周哲 所谓"异步" ,简单说就是一个任务分成两段,先执行第一段,然后转而执行其他任务,等做好了准备,再回过头执行第二段.比如,有一个任务是读取文件进行处理,异 ...

  4. spring mvc 异步_DeferredResult – Spring MVC中的异步处理

    spring mvc 异步 DeferredResult是一个可能尚未完成的计算的容器,它将在将来提供. Spring MVC使用它来表示异步计算,并利用Servlet 3.0 AsyncContex ...

  5. PHP guzzle异步请求数据,Guzzle中的异步请求

    Guzzle中的异步请求 使用Guzzle发起异步请求 Guzzle是一个PHP的HTTP客户端,它在发起http请求时不仅可以同步发起,还可以异步发起. $client = new Client() ...

  6. c语言 多个线程对同一变量执行memcpy_你可曾听过网络编程中应用线程本地存储?...

    壹:你可曾听过线程本地存储? 1. 什么是线程本地存储? 线程本地存储:thread local storage(简称TLS).也叫线程特有存储:thread specific storage(简称T ...

  7. Java中的线程本地存储

    开发人员中鲜为人知的功能之一是线程本地存储. 这个想法很简单,并且在需要数据的情况下很有用. 如果我们有两个线程,则它们引用相同的全局变量,但我们希望它们具有彼此独立初始化的单独值. 大多数主要的编程 ...

  8. 聊聊Linux中的线程本地存储(1)——什么是TLS

    从本篇开始进入另一个话题:线程本地存储(Thread Local Storage),在介绍这个概念前先说说变量和多线程的相关知识. 多线程下的变量模型 在单线程模型下,变量定义有两个维度,那就是在何处 ...

  9. node.js 中间件_Node.js中的Passport中间件(模块)

    node.js 中间件 Hi! Welcome to Node.js Authentication Series, where we'll study and program the passport ...

最新文章

  1. 和菜鸟一起学linux之DBUS基础学习记录
  2. leetcode 滑动窗口小结 (一)
  3. 台式电脑一般价钱多少_看完才明白,电脑一体机和台式机哪个好?
  4. 揭秘-选择迅捷PDF转Word转换器的原因
  5. CDialog 放到 CDockablePane里,总在外面显示?
  6. 职场白骨精必看的五个寓言
  7. Windows 环境变量的两点说明
  8. Qt QLCDNumber 13行实现 显示日期时间 颜色设置 刷新
  9. 儿童专注力训练之数图形
  10. openwrt系统安装到云服务器,云服务器安装openwrt
  11. MySQL:复合查询和内外连接
  12. 20172328 2018-2019《Java软件结构与数据结构》第六周学习总结
  13. 【数据】社区发现数据集
  14. Fluent 操作入门实例-从建模到计算结果可视化
  15. 计算机的未来展望英语作文,展望未来英语作文5篇
  16. Android root环境下设置ro.debuggable = 1
  17. ajax请求或者计算造成浏览器崩溃解决办法
  18. Shaolin(map+iterator) HDU - 4585
  19. C++实现大整数乘法
  20. Day31.只出现一次的数字

热门文章

  1. 【实习笔试面试题】2013网易互联网实习笔试算法题-找出最大连续自然数个数
  2. cutterman工具使用 0921
  3. selinum-操作表单元素-0223
  4. python-类的装饰器-主要给类添加属性用途
  5. django-模型类管理器-create方法-models属性
  6. 机器学习——Day 3 多元线性回归
  7. 从 ES 规范 中理解 this
  8. 七、Framework类库
  9. 货车运输 vijos 1843 NOIP2013 D1T3 最大生成树,并查集,(伪·LCA)
  10. SQL Tuning Advisor使用实例