首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Nodejs进阶」一文吃透异步IO和事件循环

异步I/O 概念 处理器访问任何寄存器和 Cache 等封装以外的数据资源都可以当成 I/O 操作,包括内存,磁盘,显卡等外部设备。...第二阶段:pending callback ,大部分 I/O 回调任务都是 poll 阶段执行的,但是也会存在一些上一次事件循环遗留的被延时的 I/O 回调函数,那么此阶段就是为了调用之前事件循环延迟执行的...2 任务队列 整个事件循环过程中,有四个队列(实际的数据结构不是队列)是 libuv 的事件循环中进行的,还有两个队列是 nodejs执行的分别是 promise 队列 和 nextTick... NodeJS 中不止一个队列,不同类型的事件它们自己的队列中入队。处理完一个阶段后,移向下一个阶段之前,事件循环将会处理两个中间队列,直到两个中间队列为空。...5 pending 阶段 pending 阶段用来处理此次事件循环之前延时的 I/O 回调函数。首先看一下 libuv 中执行时机。

2K20
您找到你想要的搜索结果了吗?
是的
没有找到

Nodejs深度探秘:event loop的本质和异步代码中的Zalgo问题

NodeJS代码中,一旦有异步调用产生,执行流就会将这个调用提交给它的线程池,然后直接指向异步调用后面的代码,例如: console.log(1) setTimer(()=>{console.log(...2), 0) console.log(3) 上面代码运行时输出结果是1,3,2,这是因为setTimer是异步函数主线程里不会得到执行,主线程会把这个时钟任务交给线程池,等到时钟结束后,里面的回调就会放置在上图中的时钟队列...每个阶段,主线程会从对应队列中获取数据返回给客户端,或者是将存储队列中的回调函数进行执行,当队列清空,或者访问的队列元素超过给定值后就会进入下一个阶段。...第二个阶段是操作系统某项情况下需要通知特定事件给NodeJS,例如TCP连接请求被拒绝,数据库连接失败等;idle阶段属于nodejs内部使用,主线程会执行一些nodejs内部特定回调函数执行一些内部事务...reader2对应的createFileReader函数执行后,对应的数据已经存储缓存中,于是代码直接将listener2队列中的回调元素拿出来执行,注意这个时候reader2.onDataReady

1.2K10

JS异步转同步组件——DeAsync.js原理深入分析

before,realAsyncFunction的then函数执行,cb被调用之前,js线程就会卡死原地,不执行后面的代码,直到异步过程返回后,继续打印after。...JS引擎的工作原理 我们都知道js是单线程执行的,用单线程配合异步IO,让我们开发者可以很直观地编写业务逻辑,不用担心时序错乱的问题。 下图显示了Nodejs的主体结构,很多地方都能看到它。...用户代码主线程执行,如果执行过程中,遇到一个异步调用,js引擎就会封装一个请求对象,并且注册到线程池去。...正常的js执行过程中,主线程代码结束之前,任何异步注册的回调都不会执行。...但我们通过调用deasync.runLoopOnce(),主线程代码执行完成前,强行激活了事件循环,事件循环会检查观察者,如果这时异步调用返回了结果,它的回调函数也会被执行

7K61

Javascript运行机制(Event loop)原理知道吗?不懂就来看看吧,一篇文章让你搞定

前言 写这篇文章之前,我看了很多写的不错的文章,但是每篇文章都有那么几个关键的点,很多篇文章凑在一起综合来看,才可以对这些概念有较为深入的理解。...正文 开始之前,先理解一下三个概念:堆、栈、队列 堆(Heap) 堆是一种数据结构,是利用完全二叉树维护的一组数据,堆分为两种,一种为最大堆,一种为最小堆。...event loop是一个执行模型,不同的地方有不同的实现。浏览器和NodeJS基于不同的技术实现了各自的Event Loop。 浏览器的Event Loop是html5的规范中明确定义。...同步任务和异步任务 Javascript单线程任务被分为同步任务和异步任务,同步任务会在调用栈中按照顺序等待主线程依次执行异步任务会在异步任务有了结果后,将注册的回调函数放入任务队列中等待主线程空闲的时候...然后先执行打印promise1,此时then的回调函数返回undefinde,此时又有then的链式调用,又放入微任务队列中,再次打印promise2。

50340

nodejs进程对象process的nextTick方法应用场景

nodejs中只支持单线程。操作系统中,每个应用程序都是一个进程类的实例对象。nodejs中,就是使用process对象来代表nodejs应用程序。...可以nodejs的REPL环境中或任何模块中访问process对象。 可以将process对象称为进程对象,即nodejs进程对象。...process.nextTick( callback )方法用于将一个函数推迟到代码中所书写的下一个同步方法执行完毕时或异步方法的事件回调函数开始执行时调用,该方法中使用一个参数,参数值是被推迟的函数。...)方法中的参数值为需要推荐执行函数,这个函数执行顺序是同步方法都执行完毕后,放在下一个事件循环中的开始执行的。...foo(); 上例原理是nextTick方法可用来将一个函数推迟到代码中所编写的下一个异步方法的事件回调函数开始执行时调用。

1.5K20

JavaScript中的单线程运行,宏任务与微任务,EventLoop

微任务能使得我们能够重新渲染UI之前执行指定的行为,避免不必要的UI重绘,UI重绘会使得应用状态不连续 另一些异步回调会进入 microtask queue(微任务队列) ,等待后续被调用,这些异步函数包括...当前轮的微任务优先于宏任务异步操作先执行执行完成到 loop 中,进入到下一轮。下一轮执行之前的宏任务的异步操作,比如 setTimeout 。...此时,如果这个异步任务中还有微任务,那么就会执行完成这个微任务,执行下一个异步任务。就这样一次的循环。...往下,是一个Promise.then() 的异步,跳过。最后一个是一段同步代码 console.log(2)。所以,这一轮中我们知道打印了1, 2两个值。...对比浏览器与NodeJS的不同 大部分情况下,浏览器与NodeJS的运行没有区别,唯一有区别的是第二轮事件执行的时候,如果有多个宏任务(setTimeout),浏览器会依次的执行宏任务,上一个宏任务执行完成了执行下一个宏任务

3.4K42

es6 --- Generator 函数

第一部分,ES6 中的 Generator ES6 出现之前,基本都是各式各样类似Promise的解决方案来处理异步操作的代码逻辑,但是 ES6 的Generator却给异步操作又提供了新的思路...nodejs 环境执行这段代码,打印出来的数据都在代码注释中了,也可以自己去试试。...for...of的应用示例 针对for...ofIterator对象的操作之前已经介绍过了,不过这里用一个非常好的例子来展示一下。用简单几行代码实现斐波那契数列。...一个普通的异步函数 就用 nodejs 中读取文件的函数为例,通常都这么写 fs.readFile('data1.json', 'utf-8', (err, data) => { //...Genertor中使用thunk函数 这个比较简单了,之前都讲过的,直接看代码即可。

63220

nodejs基本原理总结

一. nodejs背景 先来说说nodejs最常被提到的几个关键词,“单线程”,“非阻塞异步IO”,“事件循环”。接下来主要来通过这几个关键字总结一下nodejs的内在原理,以及引申出的一些问题。...4秒期间,计时器已经是过了两秒的,而'javascript setTimeout'这一句打印却在'javascript end'之后,即使计时器两秒后回调代码应该被执行时,因为javascript的线程处于非空闲状态...可以思考一下,读操作是线程池来控制执行的,该线程执行前,先在注册事件的内存中初始化一个状态是“执行中”,并且事件循环也已经被激活,开始轮询等待执行结果,当执行IO的线程执行完之后,再通过底层的异步IO...接口(epoll_wait/IOCP)进行通知到初始注册的任务队列内存进行变更状态,事件循环轮询到状态变成“已完成”,这时候IO事件注册时注入的回调函数得到执行权,javascript线程开始工作,整个异步过程完毕...(),close事件,setImmediate的其他回调函数 idle, prepare:仅内部使用 poll:获取新的I/O 事件,适当的条件下nodejs会阻塞在这个阶段 check:setImmediate

1.2K50

宏任务和微任务的一个小事

而在没有微任务的时代,JavaScript的执行中并没有所谓异步执行的概念,异步执行宿主环境中实现的,也就是浏览器提供了。...微任务,看定义中与(宏)任务的区别其实比较复杂,但是根据定义就可以知道,其中很重要的一点是,微任务必须是一个异步执行的任务,这个执行的时间需要在主函数执行之后,也就是微任务建立的函数执行后,而又需要在当前宏任务结束之前...其实这个问题在之前的业务开发中遇到过。由于微任务执行的时序与定义不符,导致数据出现了微小的差异。这里与Nodejs版本迭代中的实现有关。...而通过查看Nodejs版本日志发现,Nodejs环境中,11版本之前,同源的任务放在一起进行执行,也就是宏任务队列和微任务队列只有清空一个后才会执行另一个。...但是这样并不符合规范,所以我更愿意倾向于相信Nodejs团队11版本之前的实现存在错误,而在11版本后修复了这个错误。

1.2K40

关于NodeJS工作原理的五个误解

存储此信息的数据结构只是一个普通的老式 JavaScript 对象,其中对象属性是事件名称,属性的值是一个侦听器函数或侦听器函数数组。...I am the last log line 由于 event emitter 同步执行所有事件处理函数,因此 I am the last log line 调用所有监听函数完成之后才会打印。...误解2 - 所有接受回调的函数都是异步函数是同步的还是异步的取决于函数执行期间是否创建异步资源。...同步函数执行的整个过程中都会占用堆栈,方法是禁止其他任何人占用堆栈直到return 为止。相反,异步函数调度一些异步任务并立即返回,因此将自身从堆栈中删除。...由于这个原因,某些加密函数和 zlib 函数异步版本以 libuv 线程池上执行计算的方式编写,这样它们就不会阻塞事件循环。

1.6K20

原生JS灵魂之问(下), 冲刺进阶最后一公里(附个人成长经验分享)

,对于同步代码直接压入执行栈(关于执行栈,若不了解请移步之前的文章《JavaScript内存机制之问——数据是如何存储的?》)...因此会打印出这样的结果: timer1 timer2 promise1 promise2 4.nodejs 和 浏览器关于eventLoop的主要区别 两者最主要的区别在于浏览器中的微任务是每个相应的宏任务中执行的...,而nodejs中的微任务是不同阶段之间执行的。...每一个 eventLoop 阶段完成后会去检查这个队列,如果里面有任务,会让这部分任务优先于微任务执行。 第31篇: nodejs中的异步、非阻塞I/O是如何实现的?...生成器(Generator)是 ES6 中的新语法,相对于之前异步语法,上手的难度还是比较大的。因此这里我们先来好好熟悉一下 Generator 语法。 生成器执行流程 上面是生成器函数

1.9K10

息息相关的 JS 同步,异步和事件轮询

使用异步 (如 回调函数、promise、async/await),可以不用阻塞主线程的情况下长时间执行网络请求。 了解异步的工作方式之前,咱们先来看看同步是怎么样工作的。...深入研究异步JS之前,先来了解同步 JS 代码 JavaScript 引擎中执行情况。...函数代码函数执行上下文中执行,全局代码全局执行上下文中执行。每个函数都有自己的执行上下文。...这意味着这些函数阻塞了调用堆栈或主线程。因此,执行上述代码时,咱们不能执行任何其他操作,这是不理想的。 解决办法是什么? 最简单的解决方案是异步回调,各位使用异步回调使代码非阻塞。...Nodejs中,web api被c/c++ api所替代。 现在让我们回到上面的代码,看看它是如何异步执行的。

9.8K31

多图详解不同环境下的EventLoop执行机制

开始介绍它之前我们会稍微来讲讲一些简单概念。 栈 比如我们日常函数执行,实质上基于栈去操作。JS 中会存在一个调用栈,它会负责跟踪所有待执行的操作。 每当一个函数执行完成时,它就会从栈的顶部弹出。...这里我们就不得不提出事件队列的概念,所谓事件队列(Event Queue)正是负责将即将执行函数发送到栈中进行处理,它循队列数据结构保证所有发送执行的正确顺序。...Node APi 这是 NodeJs 官方指南中对于事件循环的描述,深入了解这张图之前我们先来看看 NodeJs 对于浏览器环境来说多了哪些 API 任务。...它意为当要异步地(但要尽可能快)执行某些代码时,使 setImmediate() 函数。...当 EventLoop 执行到 timer 阶段时,会拿出这个 timer 的 callback 执行它。 所以不难想象,控制台会执行这个函数打印 timer 。

59320

带你彻底弄懂Event Loop

,下一个macrotask之前,紧跟着执行UI render。...,执行callback1的时候又遇到了另一个Promise,Promise异步执行完后microtask queue中又注册了一个callback4回调函数 Step 9 Promise.resolve...,可以认为只有一个宏队列,所有的macrotask都会被加到这一个宏队列中,但是NodeJS中,不同的macrotask会被放置不同的宏队列中。...比如Promise等 浏览器中,也可以认为只有一个微队列,所有的microtask都会被加到这一个微队列中,但是NodeJS中,不同的microtask会被放置不同的微队列中。...start end 999 开始依次执行6个阶段各自宏队列中的所有任务,先执行第1个阶段Timers Queue中的所有任务,先取出callback1执行打印111,callback1函数继续向下

36210

带你彻底弄懂Event Loop前言正文总结

,下一个macrotask之前,紧跟着执行UI render。...2 但是,执行callback1的时候又遇到了另一个Promise,Promise异步执行完后microtask queue中又注册了一个callback4回调函数 Step 9 Promise.resolve...,可以认为只有一个宏队列,所有的macrotask都会被加到这一个宏队列中,但是NodeJS中,不同的macrotask会被放置不同的宏队列中。...比如Promise等 浏览器中,也可以认为只有一个微队列,所有的microtask都会被加到这一个微队列中,但是NodeJS中,不同的microtask会被放置不同的微队列中。...start end 999 开始依次执行6个阶段各自宏队列中的所有任务,先执行第1个阶段Timers Queue中的所有任务,先取出callback1执行打印111,callback1函数继续向下

52540
领券