• An asynchronous callback

Let’s start with a simple code example of an asynchronous callback

function asyncFun(callback) {
    setTimeout(() => callback('success'), 300);
}

asyncFun(function (e) {
    console.log('end', e);
})
Copy the code

We first define an asynchronous function asyncFun that takes a function argument to execute asynchronously in a setTimeout. There’s nothing to say about this simple example. But what if you need to run an error in an asynchronous function?

Function asyncFun(callback) {setTimeout(() => {if (math.random < 0.5) callback('success'); else throw new Error('fail') }, 300); } try { asyncFun(function (e) { console.log('end', e); }) } catch (err) { console.log('err', err) }Copy the code

Can this execution successfully catch an error?

The answer is no, global error. Because of the asynchronous invocation, the actual execution of the function throws an error out of the call stack of the original method and is triggered by the Node.js event loop. So how do you throw an error and deal with it outside?

Function asyncFun(callback) {setTimeout(() => {if (math.random < 0.5) callback('success'); else callback(new Error('fail')) }, 300); } asyncFun(function (e) { if (e instanceof Error) { console.log('errHere', e) } else { console.log('successs', e) } })Copy the code

Errors are also thrown via callback. The current result is as follows:

Errors can now be handled normally. However, it is up to the caller to determine the parameter type and do the corresponding processing. It’s a little too complicated.

Node.js has a convention for callback functions: error-first: if an error occurs, the error is returned as the first argument to the callback:

Function asyncFun(callback) {setTimeout(() => {if (math.random < 0.5) callback(null, 'success'); else callback(new Error('fail')) }, 300); } asyncFun(function (e) { if (e) { console.log('errHere', e) } else { console.log('successs', e) } })Copy the code

This will make the function call a lot easier.

  • Event loop

Event Loop is an important concept in Node.js. Is an effective way to ensure the efficiency of Javascript single line at the same time. We won’t discuss macro tasks, micro tasks and other concepts in EventLoop. Let’s simulate implementing a simple Event Loop.

const eventLoop = {
    queue: [],
    loop: function () {
        if (this.queue.length) {
            const callBack = this.queue.shift();
            callBack();
        }
        setTimeout(this.loop.bind(this), 100)
    },
    add: function (callBack) {
        this.queue.push(callBack);
    }
}

eventLoop.loop();
setTimeout(() => console.log('111'), 300);
setTimeout(() => console.log('222'), 600);
Copy the code

The output is as follows:

The above briefly describes asynchronous callbacks and event loops in Node.js.