当前位置: 首页 > 后端技术 > Node.js

异步、同步、阻塞、非阻塞

时间:2023-04-03 23:05:28 Node.js

参考原文链接。这一点特别适合我讲异步、同步、阻塞、非阻塞。比如普通B/S模式(同步):提交请求->等待服务器处理->处理完返回这里,意思是你提交了一个请求,没有立即返回。服务器处理完成后,*以返回值返回*例如ajax请求(异步):请求由事件触发->服务器处理->已处理。这个过程是你触发事件后,服务器立即返回,*但没有返回值*,然后当服务器处理完这件事后,通过回调、promises等方式通知你返回值。比较通俗的例子:同步:你下楼去取快递,然后快递小哥说我帮你找。在这个过程中,你等到他找到你的快递,连同快递一起退回。异步:你下楼去取快递。快递小哥说我给你找。如果你找到了,我会打电话给你,告诉你应该怎么做。阻塞和非阻塞可以这样理解。阻塞就是当你拿快递的时候,进程挂了,你什么也做不了。你只能等快递小哥告诉你答案,你才能做你的事。*非阻塞意味着,你的读取操作立即返回,但没有数据。非阻塞I/O获取完整数据的需求可以通过轮询来实现,但是对于应用程序来说,它仍然是一种同步,因为程序任何时候都需要等待IO完全返回,而等待时间,cpu要么用来遍历文件描述符的状态,要么用来休眠等待事件发生。*说到这里,我们知道js是单线程的。js的主要目的是与用户交互,以及用于操作DOM.*JavaScript的单线程,这取决于它的目的。作为一种浏览器脚本语言,JavaScript的主要目的是与用户交互和操作DOM。这就决定了它只能是单线程的,否则会带来非常复杂的同步问题。例如,假设JavaScript同时有两个线程,一个线程向某个DOM节点添加内容,另一个线程删除这个节点,那么浏览器应该以哪个线程为基础呢?*(摘自阮老师的博客)单线程就是同一时间只能做一件事情,前一件事情做完之后才能执行下一件事情。当遇到需要时间的IO事件时,问题就来了,必须等到这些结束后再进行,但是此时CPU是空闲的。这会浪费大量的计算机性能。JavaScript语言的设计者意识到,此时主线程可以不管IO设备如何,挂起等待的任务。运行稍后排队的任务。等到IO设备返回结果,再回去继续挂起的任务。***因此,所有的任务可以分为两种,一种是同步任务(synchronous),一种是异步任务(asynchronous)。同步任务是指在主线程上排队等待执行的任务,只有上一个任务执行完才能执行下一个任务;异步任务是指不进入主线程而是进入“任务队列”(taskqueue)的任务,只有当“任务队列”通知主线程有异步任务可以执行时,任务才会进入执行的主线程。***(1)所有的同步任务都在主线程上执行,形成一个执行上下文栈。(2)除了主线程之外,还有一个“任务队列”。只要异步任务有运行结果,就会在“任务队列”中放入一个事件。(3)一旦“执行栈”中的所有同步任务都执行完毕,系统就会去读取“任务队列”,看看里面有什么事件。那些对应的异步任务结束等待状态,进入执行栈,开始执行。(4)主线程不断重复上面的第三步。