JavaScript asynchronous programming – Basics

Time:2022-5-19

Ajax requests are very common in the front-end field. I believe every front-end Er has written the following code:

//Prerequisite: introducing jquery

$.ajax({
    type: 'get',
    url: '/path/to/data',
    success: function (response) {
    
    },
    error: function (errMsg) {

    }
})

Success and error in the above code are called callback functions. Based on the characteristics of JS asynchronous IO, the code means to execute the success function after the Ajax request is successful, and the error function when Ajax fails.

However, in some cases, business logic may require us to generate callback functions in multiple success States, or send multiple Ajax requests at the same time, and execute callback after all success states. This method is somewhat stretched.

1. There are multiple callback responses for a single Ajax request

//Using the above method, there are two kinds of business logic

$.ajax({
    type: 'get',
    url: '/path/to/data',
    success: function (response) {
        // todo
        
        successCallback2(response);
        successCallback3(response);
    }
})

The callback will continue after the nested callback method of callback 2 is completed. The code does not develop vertically, but horizontally, which is the callback hell in JS.

2. Multiple Ajax requests want a common callback response

//Continue with the original method, assuming that there are multiple Ajax requests and you want to execute the callback function after all are completed.

function fetchData (url, successCb, errorCb) {
    return function () {
        $.ajax({
            type: 'get',
            url: url,
            success: successCb,
            error: errorCb
        });
    }
}

function successCb () {
    console.log('success');
}

function errorCb () {
    console.log('error');
}

var fetchData1 = fetchData('/path/to/data1', successCb, errorCb);
var fetchData2 = fetchData('/path/to/data2', successCb, errorCb);

If there are two identical fetch data operations, we can only rewrite fetchdata1 if we want to operate in parallel

var fetchData1 = fetchData('/path/to/data1', fetchData2, errorCb);

fetchData1();

In fact, this method is to perform fetchdata2 operation after fetchdata1 succeeds, which is not a strictly parallel operation. Then, in the callback of fetchdata2’s success state, we can obtain the return value of two Ajax requests.

Such code is not perfect. When we are pursuing the technology stack of webpack + ES6 + Babel, we should also think about how to improve productivity and code maintainability from the most basic code.

After finding the pain point of the code in the business, we should find a way to solve it. Fortunately, today’s front-end flowers bloom, and there are already a variety of mature solutions to such problems. The next few articles will talk about the implementation methods and code principles of these asynchronous schemes in detail from simple to deep, and I have implemented a tiny version of each method. All article codes are open sourcegithubIf you have any questions, suggestions or even errors, you can send them to me in GitHub. Welcome to a heated discussion.

Starting from the next article, we will focus on how to solve the above two problems from the deferred object. If you are interested, please continue to read it.JavaScript asynchronous programming – deferred objects