Asynchronous loading

Time:2020-10-30

Asynchronous loading

1. Promise basic example

<script>
$(function(){
   function myAsync(url,data,type){
       return new Promise((resolve,reject) => {
           let requestObj;
           if(window.XMLHttpRequest){
               requestObj = new XMLHttpRequest();
           }
           else{
               requestObj = new ActiveXObject();
           }

           let sendData = "";
           if(type == "POST"){
               //JSON converts an object to a string
               sendData = JSON.stringify(data);
           }

           //The parameter true indicates asynchronous processing
           requestObj.open(type,url,true);
           requestObj.send(sendData);

           requestObj.onreadystatechange = () => {
               //ReadyState = = 4, the corresponding content parsing is completed
               if(requestObj.readyState == 4){
                   //The server successfully processed the request
                   if(requestObj.status == 200){
                       let obj = requestObj.response;
                       if( typeof obj !== 'object'){
                           obj = JSON.parse(obj)
                       }
                       resolve(obj)
                   }
                   else{
                       reject(obj)
                   }
               }
           }
       })
   }
   $("#btn").on("click",()=>{
       myAsync("http://jsonplaceholder.typicode.com/posts","GET")
           .then(
               (rsp) => {  console.log ("success! ",rsp)})
           .catch((error)=>{
               console.log(error)
           })
   });
});
</script>

2、 Promise.all Method can receive multiple promises as parameters, in the form of an array, and then call the callback function after these promises are successfully executed.

var request1 = fetch('/users.json');
var request2 = fetch('/articles.json');

Promise.all([request1, request2]).then(function(results) {
});

3、 Promise.race Is in all promise, as long as there is one end of execution, it will trigger.

var req1 = new Promise(function(resolve, reject) {
    setTimeout(function() { resolve('First!'); }, 8000);
});
var req2 = new Promise(function(resolve, reject) { 
    setTimeout(function() { resolve('Second!'); }, 3000);
});
Promise.race([req1, req2]).then(function(one) {
    console.log('Then: ', one);
}).catch(function(one, two) {
    console.log('Catch: ', one);
});

3. Async and await

The following is an excerpt from Bian Cheng’s understanding async / await of JavaScript
Original address: https://segmentfault.com/a/11…

(1) , introduction
Async is the abbreviation of “asynchronous”, while await can be regarded as the abbreviation of async wait. Async is used to declare that a function is asynchronous, while await is used to wait for the execution of an asynchronous method to complete. Await can only appear in async functions.

(2) What role does async play

The key to this problem is how the async function handles its return value! Of course, we want it to return the value we want directly through the return statement, but if it does, it doesn’t seem to matter. So write a piece of code to try and see what it will return:

async function testAsync() {
    return "hello async";
}

const result = testAsync();
console.log(result);

The output is a promise object:

Promise { 'hello async' }

So, the async function returns a promise object. Async function (including function statement, function expression and lambda expression) will return a promise object. If a direct quantity is returned in the function, async will pass this direct quantity through Promise.resolve () is encapsulated as promise object. Use the. Then () chain to handle the promise object,

testAsync().then(v => {
    console.log (v) ; // output Hello Async
});

Now, in retrospect, if the async function doesn’t return a value, it does Promise.resolve (undefined)。

Think of promise’s feature – no wait, so if you execute async function without await, it will execute immediately, return a promise object, and never block the following statements. This is the same as a normal function that returns a promise object.

(3) What is await waiting for

Generally speaking, await is assumed that await is waiting for an async function to complete. However, according to the syntax, await is waiting for an expression that evaluates to a promise object or other value (in other words, there is no special qualification).

Because async functions return a promise object, await can be used to wait for the return value of an async function – that is, await is waiting for an async function, but be aware that it is actually a return value. Notice that await is not only used to wait for promise objects, it can wait for the result of any expression. Therefore, await can be followed by ordinary function calls or direct variables. So the following example works perfectly

function getSomething() {
    return "something";
}

async function testAsync() {
    return Promise.resolve("hello async");
}

async function test() {
    const v1 = await getSomething();
    const v2 = await testAsync();
    console.log(v1, v2);
}

test();

If it doesn’t wait for a promise object, the result of the await expression is what it waits for.

If it waits for a promise object, await will be busy. It will block the following code, wait for promise object to resolve, and then get the value of resolve as the operation result of await expression.

Seeing the word “blocking” above, I feel flustered Rest assured, that’s why await must be used in async functions. Async function calls do not cause blocking, and all internal blocking is encapsulated in a promise object and executed asynchronously.

(5) What did async / await do for us
For a simple comparison: as explained above, async will encapsulate the return value of the subsequent function (function expression or lambda) into a promise object, and await will wait for the promise to complete and return its resolve result.

For example, we use setTimeout to simulate time-consuming asynchronous operations. First, we do not need async / wait

function takeLongTime() {
    return new Promise(resolve => {
        setTimeout(() => resolve("long_time_value"), 1000);
    });
}

takeLongTime().then(v => {
    console.log("got", v);
});

If async / await is used instead:

function takeLongTime() {
    return new Promise(resolve => {
        setTimeout(() => resolve("long_time_value"), 1000);
    });
}

async function test() {
    const v = await takeLongTime();
    console.log(v);
}

test();

Sharp eyed students have found that takelongtime() is not declared async. In fact, takelongtime() itself is the promise object returned. The result is the same with or without async. If you don’t understand, please go back to the “async function” above.

(6) After comparison, what are the advantages of async / await?

Async / await has the advantage of handling then chains
A single promise chain can’t find the advantage of async / await, but if you need to deal with the then chain composed of multiple promise, the advantage can be reflected (interesting, promise uses then chain to solve the problem of multi-layer callback, and now async / await is used to further optimize it).

Suppose a business is completed in multiple steps, each step is asynchronous and depends on the results of the previous step. We still use setTimeout to simulate asynchronous operations:

/**
 *Pass in the parameter n, which indicates the execution time of this function (MS)
 *The result of execution is n + 200, which will be used for the next step
 */
function takeLongTime(n) {
    return new Promise(resolve => {
        setTimeout(() => resolve(n + 200), n);
    });
}

function step1(n) {
    console.log(`step1 with ${n}`);
    return takeLongTime(n);
}

function step2(n) {
    console.log(`step2 with ${n}`);
    return takeLongTime(n);
}

function step3(n) {
    console.log(`step3 with ${n}`);
    return takeLongTime(n);
}
Now we use promise to realize the three steps

function doIt() {
    console.time("doIt");
    const time1 = 300;
    step1(time1)
        .then(time2 => step2(time2))
        .then(time3 => step3(time3))
        .then(result => {
            console.log(`result is ${result}`);
            console.timeEnd("doIt");
        });
}

doIt();

// c:\var\test>node --harmony_async_await .
// step1 with 300
// step2 with 500
// step3 with 700
// result is 900
// doIt: 1507.251ms

The output result is the parameter 700 + 200 = 900 of step3(). Doit() performs three steps in sequence, taking a total of 300 + 500 + 700 = 1500 ms, and console.time () / console.timeEnd The results are consistent.

What if async / await is used to implement it

async function doIt() {
    console.time("doIt");
    const time1 = 300;
    const time2 = await step1(time1);
    const time3 = await step2(time2);
    const result = await step3(time3);
    console.log(`result is ${result}`);
    console.timeEnd("doIt");
}

doIt();

The result is the same as the previous promise implementation, but does the code look much clearer, almost the same as the synchronization code

(7) Now, it is still three steps to change the business requirements, but each step needs the results of each previous step.

function step1(n) {
    console.log(`step1 with ${n}`);
    return takeLongTime(n);
}

function step2(m, n) {
    console.log(`step2 with ${m} and ${n}`);
    return takeLongTime(m + n);
}

function step3(k, m, n) {
    console.log(`step3 with ${k}, ${m} and ${n}`);
    return takeLongTime(k + m + n);
}

This time, we use async / await to write:

async function doIt() {
    console.time("doIt");
    const time1 = 300;
    const time2 = await step1(time1);
    const time3 = await step2(time1, time2);
    const result = await step3(time1, time2, time3);
    console.log(`result is ${result}`);
    console.timeEnd("doIt");
}

doIt();

// c:\var\test>node --harmony_async_await .
// step1 with 300
// step2 with 800 = 300 + 500
// step3 with 1800 = 300 + 500 + 1000
// result is 2000
// doIt: 2907.387ms

In addition to feeling that the execution time has become longer, it seems to be no different from the previous examples! Don’t worry. Think about it carefully. What will it look like if it is implemented in promise mode?

function doIt() {
    console.time("doIt");
    const time1 = 300;
    step1(time1)
        .then(time2 => {
            return step2(time1, time2)
                .then(time3 => [time1, time2, time3]);
        })
        .then(times => {
            const [time1, time2, time3] = times;
            return step3(time1, time2, time3);
        })
        .then(result => {
            console.log(`result is ${result}`);
            console.timeEnd("doIt");
        });
}

doIt();

Do you feel a little complicated? That pile of parameter processing is the dead end of promise scheme – parameter transfer is too troublesome, and you will feel dizzy!

Recommended Today

[cmake series] (4) test with Google test

Today, let’s talk about the cmake test. However, we are still talking about C + + testing. Cmake provides us with perfect testing support, for example, it has a special module ctest. Cmake native test support The cmake native support test is very simple, with only two functions: enable_testing() add_test(NAME <name> COMMAND <command> [<arg>…] [CONFIGURATIONS […]