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

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

2 任务队列 整个事件循环过程,有四个队列(实际的数据结构不是队列)是 libuv 的事件循环中进行的,还有两个队列是 nodejs 执行的分别是 promise 队列 和 nextTick... NodeJS 不止一个队列,不同类型的事件它们自己的队列入队。处理完一个阶段后,移向下一个阶段之前,事件循环将会处理两个中间队列,直到两个中间队列为空。...这个是 nodejs 特有的。 Microtasks 微队列 Promise :存放 promise 的回调函数。...中间队列的执行特点: 首先要明白两个中间队列并非在 libuv 中被执行,它们都是 nodejs 层执行的, libuv 层处理每一个阶段的任务之后,会和 node 层进行通讯,那么会优先处理两个队列的任务...无论是 nextTick 的任务,还是 promise 的任务, 两个任务的代码会阻塞事件循环的有序进行,导致 I/O 饿死的情况发生,所以需要谨慎处理两个任务的逻辑。

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

    Javascript异步回调细数:promise yield asyncawait

    new promise时, 需要传递一个executor()执行器——这个函数new Promise 时立即执行;Promise 的 executor 函数有两个参数,一个是 resolve,一个是...,p3Res]有了all,你就可以并行执行多个异步操作,并且一个回调处理所有的返回数据Promise.race(iterable),传入的promises数组中一个promose resolve 或者...如果可迭代对象没有一个 promise 完成(即所有的 promises 都失败/拒绝),就返回一个拒绝的 promise。目前没有几个浏览器支持。...否则,catch内捕获注意:一个promise,只有第一个reject操作失败结果,非Promisereject不会影响后面.then()的执行,并且如果reject和catch两种方式同时使用的话...我们同样使用try/catch结构,但是promises的情况下,try/catch难以处理JSON.parse过程的问题,原因是这个错误发生在Promise内部。

    81200

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

    因此会打印出这样的结果: timer1 timer2 promise1 promise2 4.nodejs 和 浏览器关于eventLoop的主要区别 两者最主要的区别在于浏览器的微任务是每个相应的宏任务执行的...,而nodejs的微任务是不同阶段之间执行的。...浏览器端,只有一种 I/O,那就是利用 Ajax 发送网络请求,然后读取返回的内容,这属于网络I/O。回到 nodejs ,其实这种的 I/O 的场景就更加广泛了,主要分为两种: 文件 I/O。...那如果换成非阻塞I/O,调用返回后我们的 nodejs 应用程序可以完成其他的事情,而操作系统同时也进行 I/O。...但是这段程度还是存在一些问题: 首先 then 两个参数不传的情况并没有处理, 假如 then 的回调执行后返回的结果(也就是上面的x)是一个 Promise, 直接给 resolve 了,这是我们不希望看到的

    2K10

    JavaScript执行机制

    相关概念浏览器我们都知道,是典型的多进程模型,但是JavaScript的运行时却是单线程的架构,我们来从浏览器出发看看具体JavaScript的运行时浏览器处于什么位置。...Promise的setTimeout延时也是0,会作为宏任务放入到事件处理线程的宏任务队列,注意,此时还未进入JS引擎线程,且事件处理线程已有两个宏任务正在等待。...由于Promise的唯一一个resolve是setTimeout,所以当前loopPromise无法执行完,只能保持pending状态。...继续执行遇到第二个await,同理正常执行testAsync函数输出步骤2,return之后注册微任务并挂起,交出线程控制权,此时微任务队列仍有两个任务:主代码块的Promise.then和第二个await...NodeJS的运行机制 Node 的 Event Loop 和浏览器的是完全不相同的东西。

    36822

    彻底搞懂nodejs事件循环_2023-03-15

    nodejs是单线程执行的,同时它又是基于事件驱动的非阻塞IO编程模型。这就使得我们不用等待异步操作结果返回,就可以继续往下执行代码。当异步事件触发之后,就会通知主线程,主线程执行相应事件的回调。...undefinednodejs里,胶水代码的主要作用是把nodejs底层实现的C/C++库暴露给js环境。...undefinedlibuv:是用C语言实现的一套异步功能库,nodejs高效的异步编程模型很大程度上归功于libuv的实现,而libuv则是我们今天重点要分析的。...,很明显,nodejs的网络I/O、文件I/O、DNS操作、还有一些用户代码都是 libuv 工作的。...既然谈到了异步,那么我们首先归纳下nodejs里的异步事件:非I/O:定时器(setTimeout,setInterval)microtask(promise)process.nextTicksetImmediateDNS.lookupI

    99330

    ES6Promise和Generator详解

    简介 ES6除了上篇文章讲过的语法新特性和一些新的API之外,还有两个非常重要的新特性就是Promise和Generator,今天我们将会详细讲解一下这两个新特性。...Promise对象代表一个异步操作,有三种状态:Pending(进行)、Resolved(已完成,又称 Fulfilled)和Rejected(已失败)。...要记住yield本身是没有返回值的。 我们需要调用generator的next方法,将异步执行的结果传进去。这就是我们request方法做的事情。...比如nodejs的: fs.readFile(filename,[encoding],[callback(err,data)]) readFile接收3个参数,其中encoding是可选的。...我们就以两个参数为例。 一般来说,我们这样调用: fs.readFile(fileA,callback); 那么有没有办法将其改写成为单个参数的function的级联调用呢?

    1.2K21

    Vue 前后端交互基础

    Promise 对象代表一个异步操作,有三种状态:pending(进行)、fulfilled(已成功)和 rejected(已失败)。...Promise 对象的状态改变,只有两种可能:从 pending 变为 fulfilled 和从 pending 变为 rejected。...resolve 函数的作用是,将 Promise 对象的状态从“未完成”变为“成功”(即从 pending 变为 resolved),异步操作成功时调用,并将异步操作的结果,作为参数传递出去;reject...函数的作用是,将 Promise 对象的状态从“未完成”变为“失败”(即从 pending 变为 rejected),异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。   ...实例,当这个数组Promise 实例全部返回时,方法执行结束 race(数组): 接收一个数组,每个数组元素都是一个 Promise 实例,当这个数组Promise 实例有一个返回时,方法执行结束

    2.1K50

    彻底搞懂nodejs事件循环

    nodejs是单线程执行的,同时它又是基于事件驱动的非阻塞IO编程模型。这就使得我们不用等待异步操作结果返回,就可以继续往下执行代码。当异步事件触发之后,就会通知主线程,主线程执行相应事件的回调。...undefinednodejs里,胶水代码的主要作用是把nodejs底层实现的C/C++库暴露给js环境。...undefinedlibuv:是用C语言实现的一套异步功能库,nodejs高效的异步编程模型很大程度上归功于libuv的实现,而libuv则是我们今天重点要分析的。...既然谈到了异步,那么我们首先归纳下nodejs里的异步事件:非I/O:定时器(setTimeout,setInterval)microtask(promise)process.nextTicksetImmediateDNS.lookupI...undefined2、其次呢,poll阶段,timeout时间未到的时候,如果有事件返回,就执行该事件注册的回调函数。timeout超时时间到了,则退出poll阶段,执行下一个阶段。

    1.1K20

    面试了20+前端大厂,整理出的面试题

    IE 事件模型该事件模型,一次事件共有两个过程,事件处理阶段和事件冒泡阶段。事件处理阶段会首先执行目标元素绑定的监听事件。...这种模型通过attachEvent 来添加监听函数,可以添加多个监听函数,会按顺序依次执行。DOM2 级事件模型该事件模型,一次事件共有三个过程,第一个过程是事件捕获阶段。...后面两个阶段和 IE 事件模型两个阶段相同。这种事件模型,事件绑定的函数是addEventListener,其中第三个参数可以指定事件是否捕获阶段执行。...基本特性1、Promise有三种状态:pending(进行)、fulfilled(已成功)、rejected(已失败)2、Promise对象接受一个回调函数作为参数, 该回调函数接受两个参数,分别是成功时的回调...移动端适配主要有两个维度:适配不同像素密度, 针对不同的像素密度,使用 CSS 媒体查询,选择不同精度的图片,以保证图片不会失真;适配不同屏幕大小, 由于不同的屏幕有着不同的逻辑像素大小,所以如果直接使用

    82530

    前端一面高频面试题(附答案)

    Promise基本特性1、Promise有三种状态:pending(进行)、fulfilled(已成功)、rejected(已失败)2、Promise对象接受一个回调函数作为参数, 该回调函数接受两个参数...3、then方法返回一个新的Promise实例,并接收两个参数onResolved(fulfilled状态的回调);onRejected(rejected状态的回调,该参数可选)4、catch方法返回一个新的...下面这些操作会导致回流:页面的首次渲染浏览器的窗口大小发生变化元素的内容发生变化元素的尺寸或者位置发生变化元素的字体大小发生变化激活CSS伪类查询某些属性或者调用某些方法添加或者删除可见的DOM元素触发回流...,但是不会影响其文档流的位置时,浏览器就会对元素进行重新绘制,这个过程就是重绘。...CSS3的盒模型有以下两种:标准盒模型、IE盒模型模型都是由四个部分组成的,分别是margin、border、padding和content标准盒模型和IE盒模型的区别在于设置width和height

    56420

    记两道关于事件循环的题

    timer2 的回调函数进入主栈并执行,打印 timer2 ② 微任务:微任务队列无任务,第二轮事件循环结束 第三轮事件循环: ① 宏任务:宏任务队列依次有 timer3 和 timer1 这两个定时器的回调函数...timer1 的回调函数进入主栈并执行,打印 timer1 ② 微任务:微任务队列无任务,第四轮事件循环结束 其二 之后又看到这么一段代码(Nodejs): let fs = require('fs'...的执行器,进而执行 readFile 函数,由于 resolve 是位于异步回调函数(尚未执行),所以这里返回的是一个处于 pending 状态的 Promise;此外,每一次迭代也会将 then...回调执行前,我们是拿不到文件内容的。 readAll 执行完毕,返回到主栈,第一次打印 4。.....of 里面的代码就是彻底的同步代码了,每一次打印 4 之后,promise 也是紧跟着打印出来的,经过前面的分析可以知道,这个时候的 promise 还处于 pending 状态,所以打印结果自然会是

    39120

    深入研究 Node.js 的回调队列

    如你所见, IO 和计时器队列,所有与异步操作有关的内容都被移交给了异步函数。 但是 promise 不同。... promise ,初始变量存储 JavaScript 内存(你可能已经注意到了)。 异步操作完成后,Node.js 会将函数(附加到 Promise)放在微任务队列。...同时它用得到的结果来更新 JavaScript 内存的变量,以使该函数不与 一起运行。...你肯sing不希望处理 promise 函数之前 close 事件执行回调函数。当服务器已经关闭时,promise 函数会做些什么呢?...# 返回 "last line" "setTimeout" 当事件循环继续执行队列的回调函数时,promise 操作完成并被添加到微任务队列: // 队列 Timer = [];

    3.8K10

    Vue$nextTick的理解

    Js是单线程的,其引入了同步阻塞与异步非阻塞的执行模式,Js异步模式维护了一个Event Loop,Event Loop是一个执行模型不同的地方有不同的实现,浏览器和NodeJS基于不同的技术实现了各自的...浏览器的Event Loop是HTML5的规范明确定义,NodeJS的Event Loop是基于libuv实现的。...测试的过程中发现了一个很有意思的现象,在上述例子的加入两个按钮,点击updateMsg按钮的结果是3 2 1,点击updateMsgTest按钮的运行结果是2 3 1。 Copy <!...pending) { pending = true; timerFunc(); } if (!cb && typeof Promise !...(2))语句的挂载,当执行微任务队列的任务时,首先会执行第一个挂载到Promise的任务,此时这个任务是运行执行队列,这个队列中有两个方法,首先会运行flushSchedulerQueue方法去触发组件的

    1.2K20

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

    文章会从以下方面: ✨ 并发模型 ✨ 浏览器的 EventLoop ✨ NodeJs 的 EventLoop ✨ 浏览器和 NodeJs EventLoop 的差距 本文会从以上四个方面带你探索不同运行环境下的...并发模型 JavaScript 我们听到最多的词可能就是所谓的“单线程”,所以导致了 JS 中所谓的异步并行模型和许多后台语言是不同的。...注意,此时我们会进入 poll 轮询阶段,此时 poll 阶段并不存在任何 IO 相关回调,返回轮询阶段他会检测到我们代码存在 setImmediate ,并且 setImmediate 的 callback...所以主调用栈调用这两个 Api 时会根据 Timeout 以及代码执行时间,造成先输出 immediate ,之后执行 timers。... EventLoop 必不可少的两个概念:Macro(宏任务)、Micro(微任务)。

    62520

    从实现一个Promise说起

    await,但是写下这篇文章之前,却不知道Promise背后发生了些什么,我一直以为的逻辑是先等待Promise构造方法的异步函数完成后,再调用then方法执行其中的函数。...IPromise { status: STATUS // 表明当前Promise的状态,不可逆,进行then添加方法时,会根据这个状态做出不同的处理 value: any // 异步函数执行成功后返回的值...} 改进后的then方法改进了两个地方 判断通过then方法注册事件时Promise的状态,一个Promise的状态应该是确定的不可逆的,即只能从PENDING状态转换为fulfilled或者reject...,当调用then方法注册事件时,如果此时这个Promise已经不是PENDING了,将会根据现在的Promise类型执行then注册的函数 每次调用then方法进行函数注册的时候都会返回一个新的Promise...接着我们考虑了注册的onFulfilled函数,如果这个函数返回的是一个Promise,则继续向它注册事件 小结 Promise本质就是一个发布订阅模式,异步函数是整个模型的驱动器,完成时调用resolve

    43330

    Promise必备知识汇总和面试情况

    后来出现的Generator函数以及Async函数也是以Promise为基础的进一步封装,可见Promise异步编程的重要性。...then方法必须返回一个新的promise,记作promise2,这也就保证了then方法可以同一个promise上多次调用。...好了,有了解决办法,我们就把代码进一步完善: class Promise { // 定义Promise状态变量,初始值为pending status = 'pending'; // 因为then...Promise是我司前端开发职位,nodejs开发职位,全栈开发职位,必问的一个知识点,主要问题会分布Promise介绍、基础使用方法以及深层次的理解三个方面,问题一般3-5个,根据面试者回答情况会适当增减...3、Promise.thenEvent Loop的执行顺序。

    43910

    从实现一个Promise说起

    await,但是写下这篇文章之前,却不知道Promise背后发生了些什么,我一直以为的逻辑是先等待Promise构造方法的异步函数完成后,再调用then方法执行其中的函数。...IPromise { status: STATUS // 表明当前Promise的状态,不可逆,进行then添加方法时,会根据这个状态做出不同的处理 value: any // 异步函数执行成功后返回的值...} 改进后的then方法改进了两个地方 判断通过then方法注册事件时Promise的状态,一个Promise的状态应该是确定的不可逆的,即只能从PENDING状态转换为fulfilled或者reject...,当调用then方法注册事件时,如果此时这个Promise已经不是PENDING了,将会根据现在的Promise类型执行then注册的函数 每次调用then方法进行函数注册的时候都会返回一个新的Promise...接着我们考虑了注册的onFulfilled函数,如果这个函数返回的是一个Promise,则继续向它注册事件 小结 Promise本质就是一个发布订阅模式,异步函数是整个模型的驱动器,完成时调用resolve

    69940
    领券