Jadual Kandungan
Node.js 的非阻塞 I/O
Node.js 的事件循环
Node.js 异步编程 - callback
Node.js 异步编程 – Promise
Node.js 异步编程 – async/await
总结
Rumah hujung hadapan web tutorial js 深入浅析Node.js中的异步

深入浅析Node.js中的异步

Jun 08, 2021 am 10:39 AM
node.js tak segerak

本篇文章给大家详细介绍一下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 阶段:这个阶段执行 timersetTimeoutsetInterval)的回调
  • I/O callbacks 阶段 :处理一些上一轮循环中的少数未执行的 I/O 回调
  • idleprepare 阶段 :仅 Node 内部使用
  • poll 阶段 :获取新的 I/O 事件, 适当的条件下 Node 将阻塞在这里
  • check 阶段 :执行 setImmediate() 的回调
  • close callbacks 阶段:执行 socketclose 事件回调

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

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

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

2.png

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

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

Node.js 异步编程 - callback

  • 回调函数格式规范
    • error-first callback
    • node-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)
}
Salin selepas log masuk

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

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

Node.js 异步编程 – Promise

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

链式调用:.then.catch

  • resolved 状态的 Promise 会回调后面的第一个 .then
  • rejected 状态的 Promise 会回调后面的第一个 .catch
  • 任何一个 rejected 状态且后面没有 .catchPromise,都会造成浏览器/ 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)
Salin selepas log masuk

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

  • 如果回调函数最终是 throw,该 Promiserejected 状态
  • 如果回调函数最终是 return,该 Promiseresolved 状态
  • 但如果回调函数最终 return 了一个 Promise ,该 Promise 会和回调函数 returnPromise 状态保持一致

Node.js 异步编程 – async/await

  • async functionPromise 的语法糖封装
  • 异步编程的终极方案 – 以同步的方式写异步
    • 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() < 0.2) {
        const error = new Error(&#39;failed&#39;);
        error.round = round;
        reject(error);
      } else {
        resolve(&#39;success&#39;);
      }
    }, 500)
  })
}
Salin selepas log masuk

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

总结

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

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

Atas ialah kandungan terperinci 深入浅析Node.js中的异步. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

AI Hentai Generator

AI Hentai Generator

Menjana ai hentai secara percuma.

Artikel Panas

R.E.P.O. Kristal tenaga dijelaskan dan apa yang mereka lakukan (kristal kuning)
4 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Tetapan grafik terbaik
4 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Cara Memperbaiki Audio Jika anda tidak dapat mendengar sesiapa
4 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Arahan sembang dan cara menggunakannya
4 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌

Alat panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Artikel tentang kawalan memori dalam Node Artikel tentang kawalan memori dalam Node Apr 26, 2023 pm 05:37 PM

Perkhidmatan Node yang dibina berdasarkan bukan sekatan dan dipacu peristiwa mempunyai kelebihan penggunaan memori yang rendah dan sangat sesuai untuk mengendalikan permintaan rangkaian besar-besaran. Di bawah premis permintaan besar-besaran, isu yang berkaitan dengan "kawalan memori" perlu dipertimbangkan. 1. Mekanisme kutipan sampah V8 dan had ingatan Js dikawal oleh mesin kutipan sampah

Aplikasi Pantas: Analisis Kes Pembangunan Praktikal PHP Asynchronous HTTP Muat Turun Berbilang Fail Aplikasi Pantas: Analisis Kes Pembangunan Praktikal PHP Asynchronous HTTP Muat Turun Berbilang Fail Sep 12, 2023 pm 01:15 PM

Aplikasi Pantas: Analisis Kes Pembangunan Praktikal PHP Asynchronous HTTP Muat Turun Berbilang Fail Dengan pembangunan Internet, fungsi muat turun fail telah menjadi salah satu keperluan asas bagi banyak laman web dan aplikasi. Untuk senario di mana berbilang fail perlu dimuat turun pada masa yang sama, kaedah muat turun segerak tradisional selalunya tidak cekap dan memakan masa. Atas sebab ini, menggunakan PHP untuk memuat turun berbilang fail secara tidak segerak melalui HTTP telah menjadi penyelesaian yang semakin biasa. Artikel ini akan menganalisis secara terperinci cara menggunakan HTTP tak segerak PHP melalui kes pembangunan sebenar.

Ketahui lebih lanjut tentang Penampan dalam Node Ketahui lebih lanjut tentang Penampan dalam Node Apr 25, 2023 pm 07:49 PM

Pada mulanya, JS hanya berjalan pada bahagian penyemak imbas Mudah untuk memproses rentetan berkod Unikod, tetapi sukar untuk memproses rentetan binari dan bukan berkod Unikod. Dan binari ialah format data peringkat terendah komputer, video/audio/program/pakej rangkaian

Bagaimana Swooole menyokong operasi SMTP tak segerak Bagaimana Swooole menyokong operasi SMTP tak segerak Jun 25, 2023 pm 12:24 PM

Dengan pembangunan dan pempopularan Internet yang berterusan, e-mel telah menjadi bahagian yang amat diperlukan dalam kehidupan dan pekerjaan orang ramai, dan SMTP (Simple Mail Transfer Protocol) ialah salah satu protokol penting untuk penghantaran e-mel. Sebagai rangka kerja komunikasi rangkaian tak segerak untuk PHP, Swoole boleh menyokong operasi SMTP tak segerak, menjadikan penghantaran e-mel lebih cekap dan stabil. Artikel ini akan memperkenalkan cara Swoole menyokong operasi SMTP tak segerak, termasuk menggunakan

Bagaimana Swooole menyokong operasi AMQP tak segerak Bagaimana Swooole menyokong operasi AMQP tak segerak Jun 25, 2023 am 08:22 AM

Memandangkan volum perniagaan Internet terus berkembang, permintaan untuk keselarasan tinggi dan prestasi tinggi semakin tinggi dan lebih tinggi, dan Swoole, sebagai rangka kerja komunikasi rangkaian untuk PHP, semakin digemari oleh pembangun. Antaranya, Swoole menyokong AMQP tak segerak, yang merupakan salah satu senario aplikasi yang lebih biasa. Jadi mari kita lihat bagaimana Swoole menyokong operasi AMQP tak segerak. Pertama, kita perlu menjelaskan apa itu AMQP. AMQP (AdvancedMessageQueuingProtocol) Advanced

Panduan Lanjutan untuk Python asyncio: Dari Pemula kepada Pakar Panduan Lanjutan untuk Python asyncio: Dari Pemula kepada Pakar Mar 04, 2024 am 09:43 AM

Pengaturcaraan Serentak dan Tak Segerak Pengaturcaraan serentak berurusan dengan berbilang tugas yang dilaksanakan secara serentak, pengaturcaraan tak segerak ialah sejenis pengaturcaraan serentak di mana tugasan tidak menyekat benang. asyncio ialah perpustakaan untuk pengaturcaraan tak segerak dalam python, yang membolehkan atur cara melaksanakan operasi I/O tanpa menyekat utas utama. Gelung peristiwa Teras asyncio ialah gelung peristiwa, yang memantau peristiwa I/O dan menjadualkan tugas yang sepadan. Apabila coroutine sedia, gelung acara melaksanakannya sehingga ia menunggu operasi I/O. Ia kemudian menjeda coroutine dan terus melaksanakan coroutine lain. Coroutines Coroutines ialah fungsi yang boleh menjeda dan menyambung semula pelaksanaan. Kata kunci asyncdef digunakan untuk membuat coroutine. Coroutine menggunakan kata kunci tunggu untuk menunggu operasi I/O selesai. Asas asyncio berikut

Cara menggunakan fungsi permintaan tak segerak dalam dokumentasi Vue Cara menggunakan fungsi permintaan tak segerak dalam dokumentasi Vue Jun 20, 2023 pm 05:55 PM

Vue.js ialah rangka kerja JavaScript bahagian hadapan yang popular yang menyediakan cara untuk membina antara muka pengguna dalam aplikasi anda. Dalam dokumentasi Vue.js, kami boleh menemui banyak maklumat berguna, terutamanya tentang cara menggunakan fungsi permintaan tak segerak. Fungsi permintaan tak segerak ialah cara untuk melaksanakan tugas tak segerak dalam aplikasi. Ia digunakan untuk mendapatkan data daripada pelayan, memproses input, mengesahkan borang, dsb. Secara umumnya, fungsi permintaan tak segerak perlu digabungkan dengan fungsi Java seperti Promise, async dan await.

Teknologi tak segerak dan tidak menyekat dalam pengendalian pengecualian Java Teknologi tak segerak dan tidak menyekat dalam pengendalian pengecualian Java May 01, 2024 pm 05:42 PM

Teknik tak segerak dan tidak menyekat boleh digunakan untuk menambah pengendalian pengecualian tradisional, membenarkan penciptaan aplikasi Java yang lebih responsif dan cekap: Pengendalian pengecualian tak segerak: Mengendalikan pengecualian dalam utas atau proses lain, membenarkan utas utama terus melaksanakan, mengelakkan penyekatan. Pengendalian pengecualian tanpa sekatan: melibatkan pengendalian pengecualian terdorong peristiwa apabila operasi I/O menjadi salah, mengelakkan sekatan benang dan membenarkan gelung acara mengendalikan pengecualian.

See all articles