preface

There are many asynchronous processing solutions in JS, and async/await is one of them. Recently, I have been learning and using KOA. On the server side, promise is rarely used, and the more elegant async/await is chosen instead. Of course, when a new scheme emerges, we need to learn not only how to write it, but also how it works.

What is the role of async/await

Async /await is well understood in the literal sense. Async means asynchronous and await means waiting, and both are used in the same way. Async is used to declare that a function is asynchronous, while await is used to wait for an asynchronous method to complete.

async

The async syntax is simple by adding a keyword to the beginning of a function, as shown in this example:

async function f() {
    return 1;
}
Copy the code

The async keyword simply means that the function returns a promise.

async function f() {
    return 1;
}
f().then((res) = > {
    console.log(res)
}) / / 1
Copy the code

The async function returns a promise object. If the function returns a value, async will simply return it wrapped in promise.resolve ().

await

‘await’ means to wait. What is he waiting for? The MDN reads:

[return_value] = await expression;
Copy the code

An expression can be a constant, a variable, a promise, a function, etc.

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(); // something hello async
Copy the code
  • Why can we only use the await keyword in async functions

The await operator is a return result, so in the case of synchronization, it will return directly.

What about in the asynchronous case? In that case, the await blocks the entire process until the result is returned before continuing with the code below.

Blocking code is a terrible thing, and async functions, wrapped in a promise, are executed asynchronously. Therefore, await can only be used in async functions. If used in normal programs, the entire program will block and the gain is not worth the loss.

Error handling in async/await

There’s not just a resolve case, there’s a reject case. Await only waits for a result, so what happens if an error occurs?

  • Use try-catch to catch errors
async function myFunction() {
  try {
    await Promise.reject('1');
  } catch (err) {
    console.log(err);
  }
}
myFunction(); / / 1
Copy the code
  • Use promise’s catch for error catching
async function myFunction() {
    await Promise.reject('1').catch((err) = > {
        console.log(err);
    });
}
myFunction(); / / 1
Copy the code

Async /await and promise

The biggest problem with Promise is that when the business is complex, the logic inside the then becomes complex, or the asynchronous nesting scenarios of loops, etc., are not beautifully written.

I’ll give you an arbitrary nesting example, and then use async/await and promise, respectively, to get a sense of the difference:

function takeLongTime(n) {
    return new Promise(resolve= > {
        setTimeout((a)= > resolve(n), n);
    });
}
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);
}
Copy the code

So what takeLongTime does is it gives you the delayed data after the delay.

Step1 is how long the first step was delayed.

Step2 represents the total delay of step 1 and step2.

Step3 represents how long step 1, step 2, and step3 are delayed.

  • Promise version
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();
Copy the code
  • Async/await version
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();
Copy the code

In this complex logic, we can see that async/await does have an advantage over THEN chains.

conclusion

Async /await is an asynchronous solution, and KOA supports this feature, so this syntactic sugar is inevitable when writing server code based on KOA, and learning and using it is a must.