异步编程async/await

async和await在干什么?

async声明一个函数是异步的,async声明的函数返回值是promise对象。

await只能用在async声明的函数内部,用于等待一个异步方法执行完成。


async的作用

async函数返回的是一个promise对象,在最外层又不能使用await去等待获取其返回值的情况下,我们只能用原来的promise方法then来处理:

async function test() {
    return '123';
}
console.log(test()); // Promise {"123"}

test().then(v => {
    console.log(v); // 123
})

promise的特点——无等待。所以在没有await的情况下,它会立即执行,返回一个promise对象,并且绝对不会阻塞后面的语句。这和普通的promise对象的函数没有任何区别。

所以关键在await。


await的作用

await等待的是一个表达式,这个表达式的计算结果是Promise对象或者其他值

function test1() {
    return '123';
}
async function test2() {
    return '456';
}

async function run() {
    const t1 = await test1();
    const t2 = await test2();
    console.log(t1, t2);
}

run(); // 123 456

如果await等待到的不是Promise对象,那么await表达式的运算结果就是它等到的东西,例如上述代码await test1()等到的是'123'。

如果await等待到的是Promise对象,那么它会阻塞后面的代码,等着Promise对象resolve,然后得到resolve的值,作为await的运算结果。

这里的阻塞,正是await为什么只能在async函数内部使用的原因。因为async函数不会造成阻塞,所以外部的代码依旧正常执行。所以阻塞仅仅只是async函数内部的阻塞。


async/await 的优势在于处理 then 链

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);
}

使用then处理:

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();
// step1 with 300
// step2 with 500
// step3 with 700
// result is 900
// doIt: 2365.155029296875 ms

使用async/await处理:

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();
// step1 with 300
// step2 with 500
// step3 with 700
// result is 900
// doIt: 3106.3837890625 ms

参考文章:https://blog.csdn.net/MrWangJB/article/details/107881183

posted @ 2022-09-02 09:39  笔下洛璃  阅读(94)  评论(0编辑  收藏  举报