async/await会引起阻塞因而影响并发吗? 所以项目里应不应该广泛的使用?
发布于 7 年前 作者 wbsifan 13065 次浏览 来自 问答

async/await 在同一个请求下, 会等待执行 那么问题是这样的机制, 会影响并发请求吗 那么项目里倒底该不该广泛的使用这个特性?

13 回复

这里有一个帖子,不晓得能不能解除你的疑惑 async/await 比 yield 好在哪里?

async 是多个异步操作的promise对象,await相当于then,你说的等待执行是什么意思,这不是同步操作,只是同步语法概念。

请见谅做为一个PHPer 一直是做同步的东西, 以下理解可能照搬同步的思维, 请校正.

  1. 一个进程同时只会处理一个请求
  2. 当一个请求处理完成时, 会接着处理下一个请求
  3. NODE的异步IO让一个请求能够快速的处理完, 所以相同的时间内能够处理更多的请求

所以问题来了, 当一个请求里使用了很多的 await, 比如每个await后面的方法要执行一秒 是不是意味着同一个请求的处理时间会花费更多, 影响后续请求的排队, 导致并发能力下降.

以上.

@wbsifan await 你可以想象成 N个callback的回调嵌套

@wbsifan 你说的没有一个是正确的…先找资料了解一下NodeJS的异步。await只是语法上的同步,Node层面基于EventLoop,说白了就是减少了CPU等待I/O的时间,在I/O请求期间,CPU继续处理其他事务

@DevinXian 所以并不会影响并发, 可以不用顾忌的正常使用是吧

@wbsifan 你对异步的本质还理解得不到位,async/await只是一种语法糖,代码执行跟你用callback写的代码并没有什么区别,本质上并不是同步代码,只是让你思考代码逻辑的时候能够以同步的思维去思考,避开回调地狱,要理解异步,首先要理解cpu的工作方式,cpu执行代码的时候,一个周期是以时间片为单位,实际上,无论是php还是node,处理同一个请求,cpu需要的计算量是一样的,在同样的时间内,cpu能做的计算量是一样的,差别在于,node只是提高了cpu的利用率。从而提高了同一时间能处理的请求数量。打个比方,你去银行办理业务,只有一个窗口在办理业务(一个cpu进程),假设有两个人(A和B)要办理银行卡(可理解为一次请求),方式一:A到窗口前,但这个时候要办卡的话,柜员告诉你,要你的身份证复印件(可理解为IO操作),这个时候,你去复印,柜员等待,回来后继续办理,A办理完成后,B接着同样的步骤。方式二:在A去复印身份证的时候,柜员受理B的办理请求, 等A回来后再受理A的业务。所以,很明显,方式二在同样多的时间内,一个窗口能办理的银行卡数量更多,因为这种方式充分利用了柜员等待的时间,那么方式一就是php处理请求的方式,在PHP中,处理IO操作的时候(比如,访问数据库,读取文件等),实际上cpu是处于等待状态,但其他资源此时得不到cpu的计算资源,属于资源浪费,cpu并没有接受下一个请求,而方式二,则是node处理的方式。所以综上所述,async/await 并不会影响node的并发数量。async/await是以同步的思维去写异步的代码。应该大力在项目中推广才是 。

@shoyer2010 受教了.

之前并没有充分理解 async/await 的实现方式, 以为是真正的同步, 其实内核依然在异步的执行.

async内是阻塞的 async外是非阻塞的 async内也可以去并发请求 如promise.all

你可以把它当成同步非阻塞

就相当于你打电话让我帮你办一件事,但是这就事我要1天才会办完,这一天之内你也可以去做其他事,

举个例子可能好理解一些: 餐厅里就餐的流程是先点餐再等餐,等餐就是要等待厨房异步制作餐品(异步IO)。 同步情况:餐厅每次只能让队列排头的一个人点餐,点完餐后服务员和顾客需要一起等待厨房制作餐品(阻塞),等到厨房将所有餐品做完拿给这个顾客,才会让下一个顾客点餐。 Nodejs异步情况:餐厅每次只能让队列排头的一个人点餐,点完餐后这个顾客就可以拿到一个号牌离开队列,服务员紧接着就会为下一位顾客服务点餐;当任何一个顾客的餐准备完毕,取餐处都会叫号(回调),拿着相应号牌的顾客去取餐处取餐。

比如点餐需要5分钟,一个厨师准备餐点需要10分钟,那么同步的方案使得餐厅的效率为5+10=每15分钟处理一个顾客的用餐需求,而Nodejs异步方案因为同时有人在点餐也同时有顾客的餐点在准备会使得餐厅的效率为取最大值每10分钟处理一个顾客的需求。

需要注意的是,顾客从点餐到等餐的等待时间是没有变的,都是5分+10分=15分钟,但是Nodejs的异步方案可以让排队的顾客等待更少的时间就能排到第一个。 如队列中第二个人的等待时间按照同步方案为5+10分钟=15分钟,Nodejs异步方案为点餐时间5分钟;第100个顾客排到第一个的等待时间同步方案为(5+10)99=1485分钟,Nodejs异步方案为599=495分钟。

所以Nodejs的异步机制是对排队性能没有影响的,反而这是Nodejs的最大的优势,这也是为什么大家都说JS本身很慢,但Nodejs能很容易驾驭高并发,Async/Await只是一种简化“异步同步化”代码的写法,本质还是Nodejs的异步机制。

@libook 感谢回复, 很形象

回到顶部