当前位置:网站首页>Nodejs events and event loops

Nodejs events and event loops

2020-12-06 21:41:04 flydean

brief introduction

be familiar with javascript Your friends should have used Events , Like the movement of the mouse , Mouse click , Keyboard input and so on . We are javascript Monitoring these events in , This triggers the corresponding processing .

alike nodejs There are also events in , And there's a special events Module for special processing .

At the same time, events and event cycles are nodejs Build asynchrony IO A very important concept of .

Today, let's learn more about .

event

nodejs Provides a dedicated module for events :lib/events.js.

Remember we were talking about using nodejs structure web Server ?

const server = http.createServer((req, res) => {
  res.statusCode = 200
  res.setHeader('Content-Type', 'text/plain')
  res.end('welcome to www.flydean.com\n')
})

here , Every request triggers request event .

nodejs At the heart of API It is based on asynchronous event driven architecture , therefore nodejs There are a lot of events in .

such as :net.Server Events are triggered every time there is a new connection ,fs.ReadStream The event is triggered when the file is opened ,stream Events are triggered when the data is readable .

Let's take a look at how to build a nodejs Events :

const EventEmitter = require('events')
const eventEmitter = new EventEmitter()

events There are two common methods , Namely on and emit.

on Used to listen for events ,emit Used to trigger events .

eventEmitter.on('fire', () => {
  console.log(' FireStarter ')
})

eventEmitter.emit('fire')

emit It can also take parameters , Let's look at the next parameter :

eventEmitter.on('fire', who => {
  console.log(` FireStarter  ${who}`)
})

eventEmitter.emit('fire', ' American imperialist ')

Let's take a look at the two parameters :

eventEmitter.on('fire', (who, when) => {
  console.log(` FireStarter  ${who} ${when}`)
})

eventEmitter.emit('fire', ' Chuanjianguo ','now')

By default ,EventEmitter Call all listeners synchronously in the order of registration . This ensures that the events are sorted correctly , It also helps to avoid race conditions and logic errors .

If asynchronous execution is required , You can use setImmediate() perhaps process.nextTick() To switch to asynchronous execution mode .

eventEmitter.on('fire', (who, when) => {
    setImmediate(() => {
      console.log(` FireStarter  ${who} ${when}`);
  });
})

eventEmitter.emit('fire', ' Chuanjianguo ','now')

besides ,events Several other methods are supported :

once(): Add a single listener

removeListener() / off(): Remove the event listener from the event

removeAllListeners(): Remove all listeners for the event

The event loop

We know nodejs Is running in a single threaded environment , Only one thing at a time .

This is the way to deal with it , It avoids the problem of data synchronization in multithreading environment , Greatly improve the processing efficiency .

The so-called event cycle , It means that the processor is in a program cycle , After processing the events of this cycle , Will enter the next event cycle , Deal with the next event cycle , Such a cycle, a cycle of cycles .

Blocking of the event loop

If we are in the process of event processing , The processing of an event is blocked , It will affect the execution of other events , So we can see in JS in , Almost all IO It's all non blocking . That's why javascript There are so many reasons for callback in .

An example of an event loop is

Let's take a simple example of a loop :

const action2 = () => console.log('action2')

const action3 = () => console.log('action3')

const action1 = () => {
    console.log('action1')
    action2()
    action3()
}

action1()

The above code output :

action1
action2
action3

Stacks and message queues

We know that calls between functions are implemented through the stack , In the example above , Our call sequence is also implemented through the stack .

But not all the methods in the function will be put on the stack , There are also methods that will be put into the message queue .

Let's give you another example :

const action2 = () => console.log('action2')

const action3 = () => console.log('action3')

const action1 = () => {
    console.log('action1')
    setTimeout(action2, 0)
    action3()
}

action1()

The results of the above code run :

action1
action3
action2

The result is different . This is because settimeout Trigger timer , When the timer expires , The callback function will be put into the message queue to be processed , Instead of putting it on the stack .

The event loop takes precedence over events in the stack , Only when there is no data in the stack , To consume events in the message queue .

Although in the example above setTimeout Of timeout Time is 0, But we have to wait until action3 Only when the execution is completed can the .

Be careful ,setTimeout Medium timeout It's not waiting in the current thread , It's a browser or something JS To be called by the execution environment .

Job queue and promise

ES6 Medium Promise The concept of job queue is introduced , Using the job queue will execute the results of asynchronous functions as soon as possible , Not at the end of the call stack .

for instance :

const action2 = () => console.log('action2')

const action3 = () => console.log('action3')

const action1 = () => {
    console.log('action1')
    setTimeout(action2, 0)
    new Promise((resolve, reject) =>
        resolve(' belong action3 after 、action2 Before ')
    ).then(resolve => console.log(resolve))
    action3()
}

action1()

Output results :

action1
action3
 belong action3 after 、action2 Before 
action2

This is because , Before the end of the current function resolve Of Promise Will be executed immediately after the current function .

In other words, the stack is executed first , Then execute the job queue , Finally, the message queue is executed .

process.nextTick()

Let's first give you a definition called tick, One tick It means an event cycle . and process.nextTick() In the next event loop tick Before the start , Call this function :

process.nextTick(() => {
  console.log('i am the next tick');
})

therefore nextTick It must be better than message queuing setTimeout Be quick .

setImmediate()

nodejs Provides a setImmediate Method , To execute the code as soon as possible .

setImmediate(() => {
  console.log('I am immediate!');
})

setImmediate The function in is executed in the next iteration of the event loop .

setImmediate() and setTimeout(() => {}, 0) The function of the is basically similar . They all run in the next iteration of the event loop .

setInterval()

If you want to execute some callback functions on a regular basis , You need to use setInterval.

setInterval(() => {
  console.log(' every other 2 Once per second ');
}, 2000)

To clear the scheduled tasks above , have access to clearInterval:

const id = setInterval(() => {
  console.log(' every other 2 Once per second ');
}, 2000)

clearInterval(id)

Be careful ,setInterval Every time n MS starts a function , Whether the function is finished or not .

If a function takes too long to execute , Will cause the next function to execute at the same time , How to solve this problem ?

We can consider calling again inside the callback function setTimeout, This forms recursive setTimeout call :

const myFunction = () => {
  console.log(' When it's done , Partition 2s Re execution !');

  setTimeout(myFunction, 2000)
}

setTimeout(myFunction, 2000)
The author of this article :flydean Program those things

Link to this article :http://www.flydean.com/nodejs-event/

In this paper, the source :flydean The blog of

Welcome to my official account. :「 Program those things 」 The most popular interpretation , The deepest dry goods , The most concise tutorial , There are so many tricks you don't know about waiting for you to discover !

版权声明
本文为[flydean]所创,转载请带上原文链接,感谢
https://chowdera.com/2020/12/20201206213934851f.html