深入浅析Node.js中的异步

本篇文章给大家详细介绍一下node.js中的异步。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。

深入浅析Node.js中的异步

关于 Node.js 异步,绕不开两点:非阻塞 I/O事件循环。也正是因为这两点,Node.js 才能被称为高性能并运用到线上环境中,那么下面来了解一下 Node.js 的异步机制和使用方式吧!【推荐学习:《nodejs 教程》】

Node.js 的非阻塞 I/O

I/O 即 Input/Output,一个系统的输入和输出。阻塞 I/O 和非阻塞 I/O 的区别就在于系统接收输入再到输出期间,能不能接收其他输入

以点菜吃饭为例子:去饭堂点菜吃饭需要排队等待,在这个过程中,阿姨每次只能接待一个人,“点菜-阿姨抖勺装菜-把饭菜给到你”这个过程中阿姨并不能接收其他人的点菜,这个就是阻塞 I/O;而去餐馆点菜吃饭,去到餐馆就可以跟服务员你要吃番茄炒蛋,服务员记下来之后交给后厨,这时候来了另一桌人就把服务员招呼过去说想吃小龙虾,也就是说,在把菜给你上上来之前服务员接收了其他人的点菜,那这个就是非阻塞型 I/O。

理解非阻塞 I/O 的要点在于

确定一个进行 Input/Output 的系统思考在 I/O 过程中,能不能进行其他 I/O

那在点菜吃饭这个例子中,一个进行 Input/Output 的系统就是点餐-后厨(阿姨)处理-上菜这样一个能让你吃上饭的系统;点餐就是 Input,上菜就是 Output,在这个例子中判断两者是非阻塞型还是阻塞型的关键就在于在点菜上菜这个过程中能不能接受其它的点菜上菜。就好比你点了个佛跳墙,等上菜可能就要好久了,然后来的人都是点一些简单的菜品,一分钟炒一份炒粉的那种,可能就是来来回回几波人之后都还没能给你上菜。

而 Node.js 它是用来操纵计算机的,一些如读取文件之类的操作是非常耗时的,要是不能进行其它的 I/O,那么处理效率就很会很低了,这也是 Node.js 是非阻塞型 I/O 的一个原因。

Node.js 的事件循环

Node.js 启动的时候会初始化由 libuv 提供的事件循环,每次的事件循环都包含6个阶段,这6个阶段会在每一次的事件循环当中按照下图当中的顺序反复执行,如下图:

1.png

timers 阶段:这个阶段执行 timer(setTimeout、setInterval)的回调I/O callbacks 阶段 :处理一些上一轮循环中的少数未执行的 I/O 回调idle,prepare 阶段 :仅 Node 内部使用poll 阶段 :获取新的 I/O 事件, 适当的条件下 Node 将阻塞在这里check 阶段 :执行 setImmediate() 的回调close callbacks 阶段:执行 socket 的 close 事件回调

每个阶段都有一个先入先出的(FIFO)的用于执行回调的队列,事件循环运行到每个阶段,都会从对应的回调队列中取出回调函数去执行,直到队列当中的内容耗尽,或者执行的回调数量达到了最大

然后事件循环就会进入下一个阶段,然后又从下一个阶段对应的队列中取出回调函数执行,这样反复直到事件循环的最后一个阶段。而事件循环也会一个一个按照循环执行,直到进程结束。

事件循环当中的6个宏队列和微队列的关系如下:微队列(microtask)在事件循环的各个阶段之间执行,或者说在事件循环的各个阶段对应的宏队列(macrotask)之间执行。

2.png

这里有一个特别容易混淆的版本改变:

如果是 Node10 及其之前版本:宏队列当中的有几个宏任务,是要等到宏队列当中的所有宏任务全部执行完毕才会去执行微队列当中的微任务如果是 Node11 及之后版本:一旦执行一个阶段里对应宏队列当中的一个宏任务(setTimeout,setInterval 和 setImmediate 三者其中之一,不包括I/O)就立刻执行微任务队列,执行完微队列当中的所有微任务再回到刚才的宏队列执行下一个宏任务。这就跟浏览器端运行一致了。

Node.js 异步编程 – callback

回调函数格式规范error-first callbacknode-style callback第一个参数是 error,后面的参数才是结果。

// 第一个参数是错误捕获interview(function (err, res) {  if (err) {    console.log('cry')    return;  }  console.log('smile')})function interview(callback) {  setTimeout(() => {    if (Math.random() > 0.2) {      callback(null, 'success')    } else {      callback(new Error('fail'))    }  }, 500)}

登录后复制

异步流程控制:回调地狱、异步并发等问题

npm:async.js;可以通过 async.js 来控制异步流程thunk:一种编程方式

Node.js 异步编程 – Promise

可以通过字面意思理解,Promise 是承诺的意思;当前事件循环得不到的结果,但未来的事件循环会给到你结果它是一个状态机,状态一旦确定为 resolved 或 rejected 就不会改变pending:初始状态,还没得到结果的状态fulfilled / resolved:成功状态rejected:失败状态

链式调用:.then 和 .catch

resolved 状态的 Promise 会回调后面的第一个 .thenrejected 状态的 Promise 会回调后面的第一个 .catch任何一个 rejected 状态且后面没有 .catch 的 Promise,都会造成浏览器/ Node 环境的全局错误

// promise的状态转换以及通过then获取内容const promise = new Promise((resolve, reject) => {  setTimeout(function () {    resolve(3);    // reject(new Error(4))  }, 500)})promise.then(function (result) {  console.log(result)}).catch(function (err) {  console.log(err)})setTimeout(() => {  console.log(promise)}, 800)

登录后复制

执行 then 和 catch 会返回一个新 Promise,该 Promise 最终状态根据 then 和 catch 的回调函数的执行结果决定

如果回调函数最终是 throw,该 Promise 是 rejected 状态如果回调函数最终是 return,该 Promise 是 resolved 状态但如果回调函数最终 return 了一个 Promise ,该 Promise 会和回调函数 return 的 Promise 状态保持一致

Node.js 异步编程 – async/await

async function 是 Promise 的语法糖封装异步编程的终极方案 – 以同步的方式写异步await 关键字可以“暂停” async function 的执行await 关键字可以以同步的写法获取 Promise 的执行结果try-catch 可以获取 await 所得到的错误

(async function () {  await findJob()  console.log('trip')})()async function findJob() {  try {    // 进行三轮面试    await interview(1);    await interview(2);    await interview(3);    console.log('smile')  } catch (e) {    console.log('cry at ' + e.round)  }}// 进行第round轮面试function interview(round) {  return new Promise((resolve, reject) => {    setTimeout(() => {      if (Math.random() 

这是一个穿越事件循环存在的 function。

总结

登录后复制理解非阻塞 I/O 主要在于确定一个进行 I/O 的系统,然后思考判断能不能进行其它 I/O。Node.js 的事件循环在 Node11 版本及之后是和浏览器的事件循环运行一致的,要注意区分。Node.js 异步编程的规范是第一个参数是 error,后面的才是结果。Promise是一个状态机,初始状态为 pending,一旦确定状态为 resolved 或 rejected 就不会改变,可以通过 .then 和 .catch 进行链式调用。async/await 以同步的方式写异步,是异步编程的终极解决方案。

更多编程相关知识,请访问:编程视频!!

以上就是深入浅析Node.js中的异步的详细内容,更多请关注【创想鸟】其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。

发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/2634280.html

(0)
上一篇 2025年3月7日 04:31:08
下一篇 2025年2月25日 21:21:26

AD推荐 黄金广告位招租... 更多推荐

相关推荐

  • 浅谈Nodejs中的模块规范

    本篇文章给大家详细了解一下nodejs中的模块规范。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。 模块规范是构建一个大型 Node.js 应用的基础,所以非常重要;Node.js 模块规范也就是 CommonJS 模块规…

    2025年3月7日 编程技术
    200
  • 浅谈使用Node.js搭建一个简单的 HTTP 服务器

    本篇文章给大家使用node.js搭建一个简单的 http 服务器来试着操纵计算机资源。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。 什么是 HTTP 服务? HTTP 协议是什么? 超文本传输协议,一个应用层协议,一个在…

    2025年3月7日 编程技术
    200
  • 深入了解Node.js中的Koa框架

    本篇文章给大家详细介绍一下node.js中的koa框架。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。 在前文已经简单的了解了 Express 框架,并且使用该框架对石头剪刀布游戏进行了改造,那么来看看 Koa 框架和 E…

    2025年3月7日
    200
  • 浅谈Nodejs中的可读流,可读流如何实现?

    本篇文章给大家介绍一下nodejs中的流(stream),看看node可读流的实现方法。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。 stream的概念 流(stream)是 Node.js 中处理流式数据的抽象接口。 …

    2025年3月7日 编程技术
    200
  • 深入了解Node.js的中Worker Threads(工作线程)

    【推荐学习:《nodejs 教程》】 理解 Node 的底层对于理解 Workers 是很有必要的。 当一个 Node.js 的应用启动的同时,它会启动如下模块: 一个进程一个线程事件循环机制JS 引擎实例Node.js 实例 一个进程:p…

    2025年3月7日
    200
  • 深入浅析Node.js中的内置模块

    本篇文章带大家了解一下node.js中的内置模块,看看node.js内置模块运行机制,通过示例简单介绍一下eventemitter (观察者模式)。 Node.js 架构图 内置模块 一些栗子 File System 操作文件的 APIPr…

    2025年3月7日
    200
  • 深入了解Node.js中的非阻塞 I/O

    说到 Node.js,大家大概率听过一堆让人头晕的专有名词 关于异步,主要是事件循环和**非阻塞 I/O,**正式因为这两点 Node.js 才能称作高性能。 因此搞清楚 Node.js 的异步机制和使用方法是很重要的 Node.js 的非…

    2025年3月7日
    200
  • 一文快速了解Node.js中的事件循环

    本篇文章带大家了解一下node.js异步编程中的事件循环。事件循环是实现node非阻塞i/o非常重要的一部分!事件循环,非阻塞i/o都是属于libuv这个c++库的底层能力。理解了事件循环,非阻塞i/o就理解了node的异步是怎样运行的! …

    2025年3月7日
    200
  • 浅谈nodejs执行bash脚本的几种方案

    nodejs如何执行bash脚本?本篇文章给大家介绍一下node执行bash脚本的几种方案。 前言 最近在学习bash脚本语法,但是如果对bash语法不是熟手的话,感觉非常容易出错,比如说:显示未定义的变量shell中变量没有定义,仍然是可…

    2025年3月7日
    200
  • 一文快速了解Nodejs中crypto模块的用法

    crypto是node.js中实现加密和解密的模块,下面本篇文章带大家了解一下crypto模块,介绍一下利用crypto模块进行散列(哈希)算法、hmac算法、对称加密、非对称加密的方法。 1. crypto crypto是node.js中…

    2025年3月7日 编程技术
    200

发表回复

登录后才能评论