Without further ado, the book continues.
The node of the eventloop
Node is also a single thread, and the browser is slightly different, in dealing with eventloop from the API level, node increased by two methods process. NextTick, setImmediate
Eventloop is a library based on Libuv. What is the implementation mechanism of this library?
The official website explains:
- Timers: Indicates that the execution of the current phase is carried out
setTimeout()
和setInterval()
The scheduling callback function of.- Pending callbacks: I/O callbacks that are deferred until the next iteration of the loop.
- Idle, prepare: used only in the system.
- Poll: Retrieves new I/O events. Perform I/ O-related callbacks (in almost all cases, except for closed callback functions, those made by timers and
setImmediate()
Out of schedule), the rest of the case Node will block at this point in due course.- Check:
setImmediate()
This is where the callback function is executed.- Close callbacks: Some closed callbacks such as socket.on(‘close’,…) .
setTimeout & setImmediate
show me the code:
setTimeout(() = > {
console.log('timeout');
}, 0);
setImmediate(() = > {
console.log('immediate');
});
Copy the code
Running results in node environment are as follows:
timeout
immediate
Copy the code
or
immediate
timeout
Copy the code
Here’s the official explanation:
First, the order in which timers are executed will vary depending on the context in which they are invoked.
Secondly, if it is called from inside the main module, the timing is subject to process constraints.
SetImmediate is always called a finite number of times within an I/O loop.
To paraphrase one blogger:
The main advantage of using setImmediate over setTimeout is that setImmediate always executes in front of all timers during an I/O cycle, regardless of how many timers exist.
process.nextTick()
This API is similar to the Promise or MutationObserver microtask implementation in yesterday’s article and can be inserted at any time in a block of code to ensure that the next macro task is executed before it starts.
Show me the code:
class Lib extends require('events').EventEmitter {
constructor () {
super(a)this.emit('init')}}const lib = new Lib()
lib.on('init'._= > {
console.log('init! ')})Copy the code
As you can see from the code snippet above, console never executes. Let’s see how process.nextTick can handle output problems:
class Lib extends require('events').EventEmitter {
constructor () {
super()
process.nextTick(_= > {
this.emit('init')}}}Copy the code
Isn’t it easy? When the main thread of the node is executed, the eventloop process is triggered to search for the wrong microtask. If the microtask queue is not empty, the init event is sent.
The same can be done on the browser side with promise.resolve ().