The problem is illustrated below

  • When button A is pressed, the ajax request data is displayed in the Input Type =text box, as is button B.

  • The problem is that if you press A first, the Ajax is sent, but the data is not returned, we can’t wait, press B immediately, and the data requested by A button is returned first, which is embarrassing. If you press B, the data returned by A button is displayed first. How to solve this problem?

This problem is explained in my previous article, the second problem is the solution https://juejin.cn/post/1, we will expand on this problem today

What is the asynchronous running mechanism of JS

Below is a diagram explaining the asynchronous queue, along with the text (from Teacher Ruan Yifeng’s blog)

(1) All synchronization tasks are executed on the main thread, forming an execution context stack. (2) There is another one outside the main thread"Task queue"Task Queue. As soon as the asynchronous task has the result of running, in"Task queue"Place an event in. (3) once"Execution stack"After all synchronization tasks are completed, the system reads the data"Task queue"See what's going on in there. Those corresponding asynchronous tasks then end the wait state, enter the execution stack, and start executing. (4) The main thread repeats step 3 above.Copy the code

This is just for intermediate or lower level people like me to popularize the JS asynchronous operation principle. After that, let’s look at an asynchronous problem code

var res = [];  
  
functionresponse(data) { res.push( data ); } // ajax(..) Is an Ajax function provided in one of the libraries."http://some.url.1", response );  
ajax( "http://some.url.2", response );    
Copy the code

The problem arises. What if we assume that the desired behavior is the result of calling “http://some.url.1” in res[0] and “http://some.url.2” in res[1]? The solution is as follows

var res = [];  
function response(data) {  
    if (data.url == "http://some.url.1") {  
        res[0] = data;  
    }  
  
    else if (data.url == "http://some.url.2") { res[1] = data; } } // ajax(..) Is an Ajax function provided in one of the libraries."http://some.url.1", response );  
ajax( "http://some.url.2", response );  
Copy the code

The above scenario is used when multiple concurrent functions share the DOM, so the callback function can be modified to look like this

var res = [];  
function response(data) {  
    if (data.url == "http://some.url.1"CallbackA (data) {callbackA(data)}else if (data.url == "http://some.url.2"CallbackB (data)}} // ajax(..) Is an Ajax function provided in one of the libraries."http://some.url.1", response );  
ajax( "http://some.url.2", response );  
Copy the code

Ok, so we came up with a solution to the concurrent DOM sharing problem that I saw in a book called “You Don’t Know javascript.” The test goes on, “Don’t use this method, because the data that depends on the back end has to contain data.url, which is the url property.” Does the front end solve this problem independently? Let’s make a change in Response, set a global variable

var status; / / value is undefinedCopy the code

When we click the A button, we change the value of status to A

status = "A";
Copy the code

We change the value of status to B when we click the B button

status = "B";
Copy the code

So resopnse will look like this:


function response(data) {  
    var status;
    if(status = "A") {// The status changes to "A" after clicking on button A, so the callback function of button B is not executed. The callback function of callbackA() A is executed.else if(status = "B"{// If you click the B button, the status changes to "B", so the callback function of button A is not executed. The callback function of callbackB() is executed.}}Copy the code

This solves the problem that point A shows only A’s data and point B shows only B’s data.

Here we continue to expand on this topic, see the following scenario

var a,b;
function foo(x) {
    a = x * 2;
    baz();
}

function bar(y) {
    b = y * 2;
    baz()
}

function baz() { console.log(a+b) } // ajax(..) Is an Ajax function provided in one of the libraries."http://some.url.1", response );  
ajax( "http://some.url.2", response ); 
Copy the code

Our purpose is to wait for both A and B to return asynchronously before running baz. The solution is as follows

var a,b;

function foo(x) {
    a = x * 2;
    if(a && b) { baz(); }}function bar(y) {
    b = y * 2;
    if(a && b) { baz(); }}function baz() { console.log(a+b) } // ajax(..) Is an Ajax function provided in one of the libraries."http://some.url.1", response );  
ajax( "http://some.url.2", response ); 
Copy the code

Then, for another scenario, look at the following code

var a;

function foo(x) {
    
    a = x * 2
    baz();
 
}

function bar(x) {
    a = x / 2;
    baz();
}

function baz() { console.log(a) } // ajax(..) Is an Ajax function provided in one of the libraries."http://some.url.1", response );  
ajax( "http://some.url.2", response ); 

Copy the code

The value of A is going to change twice, and the requirement is to change a only once, the first time, and then not the second time

var a;
function foo(x) {
    if(!a) {
    a = x * 2;
    baz();
    }
}

function bar(y) {
    if(!a) {
    a = x / 2;
    baz();
    }
}

function baz() { console.log(a) } // ajax(..) Is an Ajax function provided in one of the libraries."http://some.url.1", response );  
ajax( "http://some.url.2", response ); 
Copy the code

I’m going to write an essay on how to solve asynchronous problems with Promises (I’ve read an article about natively implementing promises, and I’ll cover the next simple, but not complete, promise implementation code, just to make it easier for you to understand the inner workings of promise implementation). Need 20 images, each 10 asynchronous request, the request of 10 images, so a total of two times to request, and requires each request 10 images are received in sequence, such as the first request is sent li-ying zhao images, the second request is request Zhang Sanfeng pictures, pictures for receiving order is li-ying zhao Zhang Sanfeng to… And so on.