Home >Web Front-end >JS Tutorial >An in-depth analysis of asynchrony in Node.js

An in-depth analysis of asynchrony in Node.js

青灯夜游
青灯夜游forward
2021-06-08 10:39:472468browse

This article will give you a detailed introduction to asynchronous in Node.js. It has certain reference value. Friends in need can refer to it. I hope it will be helpful to everyone.

An in-depth analysis of asynchrony in Node.js

About Node.js Asynchrony, two points cannot be avoided: Non-blocking I/O and Event loop . It is precisely because of these two points that Node.js can be called high-performance and be used in online environments. So let’s learn about the asynchronous mechanism and usage of Node.js! [Recommended learning: "nodejs Tutorial"]

Non-blocking I/O of Node.js

    ##I/O is
  • Input/Output, the input and output of a system.
  • The difference between blocking I/O and non-blocking I/O lies in whether
  • the system can receive other input during the period from input to output.
Take ordering food as an example: you need to queue up to order food in the canteen. During this process, the aunt can only receive one person at a time. "Order - Aunt shakes the spoon to load the food - In the process of "bringing the food to you", the aunt cannot accept other people's orders. This is blocking I/O; when you go to a restaurant to order food, you can tell the waiter that you want to eat tomatoes when you go to the restaurant. Scrambled eggs, the waiter wrote it down and handed it to the chef. At this time, another table came and called the waiter over and said he wanted to eat crayfish. In other words, the waiter

accepted the other dishes before serving them to you. Human order, then this is non-blocking I/O. The key to understanding non-blocking I/O is to

Determine a system for
    Input
  • /Output . Think about whether other I/O
  • can be performed during the I/O process.
  • In the example of ordering food, a system that performs
  • Input
/

Output is ordering - processing by the kitchen (aunt) - serving Such a system that allows you to eat; ordering food is Input, and serving food is Output. In this example, the key to judging whether the two are non-blocking or blocking is During the process of ordering and serving, can I accept other orders and be served? It's like if you order a Buddha Jumps Over the Wall, it may take a long time to wait for the food to be served. Then the people who come will order some simple dishes, the kind of stir-fried noodles that can be fried in one minute. Maybe after a few waves of people come and go, I haven't been able to serve you food yet. Node.js is used to control the computer. Some operations such as reading files are very time-consuming. If other I/O cannot be performed, the processing efficiency will be very low. Yes, this is one reason why Node.js is non-blocking I/O.

Event loop of Node.js

Node.js will initialize the event loop

provided by libuv when it is started. Each event loop They all contain 6 stages. These 6 stages will be executed repeatedly in each event loop in the order shown in the figure below, as shown below:

An in-depth analysis of asynchrony in Node.js

timers
    Phase: This phase executes the callbacks of
  • timer (setTimeout, setInterval) I/O callbacks
  • Phase: Handle some unexecuted I/O callbacks from the previous cycle
  • idle
  • ,
  • prepare Phase: Only used internally by Node poll
  • Stage: Get new I/O events, Node will block here under appropriate conditions
  • check
  • Stage: Execute
  • setImmediate( )'s callbackclose callbacks
  • Stage: Execute
  • socket's close event callback
  • Each stage has a first-in-first-out (FIFO) queue for executing callbacks. When the event loop runs to each stage, the callback function will be taken out from the corresponding callback queue for execution until the contents of the queue are consumed. exhausted, or the number of callbacks executed reached the maximum
.

Then the event loop will enter the next stage, and then the callback function will be taken out from the queue corresponding to the next stage and executed, and this will be repeated until the last stage of the event loop. The event loop will also be executed one by one until the process ends.

The relationship between the six macro queues and micro queues in the event loop is as follows: Micro queue (

microtask

) is executed between various stages of the event loop, or in each stage of the event loop Executed between corresponding macro queues (

macrotask).

Here is a particularly confusing version change: An in-depth analysis of asynchrony in Node.js

  • If it is Node10 and previous versions: There are several macro tasks in the macro queue, and the micro tasks in the micro queue will not be executed until all macro tasks in the macro queue are completed.
  • If it is Node11 and later versions: Once a macro task in the corresponding macro queue in a stage is executed (setTimeout, setInterval and setImmediate among the three (excluding I/O), execute the microtask queue immediately, execute all the microtasks in the microqueue, and then return to the macroqueue to execute the next macrotask. This is consistent with the browser-side operation.

Node.js Asynchronous Programming - callback

  • Callback function format specification
    • error-first callback
    • node-style callback
  • ##The first parameter is
  • error, followed by Parameters are the result.
  • // 第一个参数是错误捕获
    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)
    }
Asynchronous process control: callback hell, asynchronous concurrency and other issues

  • npm: async.js; can be passed async.js To control asynchronous processes
  • thunk: A programming method

Node.js asynchronous programming – Promise

    can be understood literally,
  • Promise means promise; the current event loop cannot get the result, but the future event loop It will give you the result
  • It is a state machine. Once the state is determined to be
  • resolved or rejected it will not change
    • pending : Initial state, the state that has not yet obtained the result
    • fulfilled / resolved: Successful state
    • rejected : Failure status
Chain call:

.then and .catch

  • resolved The Promise of the state will call back the first .then
  • rejected of the state Promise Will call back the first .catch
  • of any
  • rejected status and no Promise## followed by .catch #, will cause a global error in the browser/Node environment
    // 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)
  • Executing
then

and catch will return a new Promise, The Promise final state is determined based on the execution results of the then and catch callback functions

if the callback function ultimately is
    throw
  • , the Promise is rejected status If the callback function eventually is
  • return
  • , the Promise is resolved StatusBut if the callback function finally
  • return
  • returns a Promise, the Promise will be the same as the callback functionreturn’s Promise state remains consistent
Node.js Asynchronous Programming –

async/await

    async function
  • is the syntactic sugar encapsulation of PromiseThe ultimate solution for asynchronous programming – writing asynchronously in a synchronous manner
    • await
    • The keyword can "pause" the execution of async function
    • await
    • The keyword can be obtained in a synchronous way# The execution result of ##Promisetry-catch
    • can obtain the error obtained by
    • 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)
        })
      }
    This is a
  • function
that exists through the event loop.

Summary

Understanding non-blocking I/O mainly lies in

determining a system that performs I/O, and then thinking about whether other I/O can be performed /O
    .
  • Node.js’ Event loop
  • In Node11 version and later, it runs the same as the browser’s event loop, so please pay attention to the distinction.
  • Node.js asynchronous programming specification is that the first parameter is error
  • , and the following is the result.
  • Promise
  • is a
  • state machine, the initial state is pending, once the state is determined to be resolved or rejected will not change, and chain calls can be made through .then and .catch. async
  • /
  • await Writing asynchronous in a synchronous way is the ultimate solution to asynchronous programming. For more programming related knowledge, please visit:
  • Programming Video
! !

The above is the detailed content of An in-depth analysis of asynchrony in Node.js. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:juejin.cn. If there is any infringement, please contact admin@php.cn delete