乐趣区

JavaScript-异步之asyncawait摘

写在前面

本文内容及代码均摘取出自一歩的相关教程。
本文仅作为个人笔记练习代码使用(所有的代码都需要自己手动敲上几遍),内容上也精简了很多。
相关知识还请阅读原文:异步神器 async-await

async-await

  • async-await 是 promise 和 generator 的语法糖;
  • async 返回的是一个 promise 对象,即可以使用 then 添加回调;
  • await 只能在 async 的上下文中使用,不然会报错;
  • await 可以等待两种返回值,promise 或其他:

    • promise:造成异步函数停止执行,并等待 promise 的 resolve;
    • 其他:立即执行
  • async-await 的错误处理(try-catch);
  • async-await 的并行处理(Promise.all);

上述总结具体代码演示如下:

// async 返回 promise;
async function demo1() {var num = Math.random();
    return num; // 相当于 Promise.resolve(num);
}
demo().then(value => {alert(value);
})
// await 只能在 async 上下文中使用
function notAsyncFunc() {return await Math.random();
}
notAsyncFunc();
// Uncaught SyntaxError: await is only valid in async function 

async function demo2() {for(i=0;i<5;i++) {await console.log(Math.random());
    }
}
demo2(); // 可以正常执行,打印 5 个随机数

async function errorDemo2() {for(i=0;i<5;i++) {setTimeout(()=>{await console.log('test2')}))
    }
}
errorDemo2();
// Uncaught SyntaxError: await is only valid in async function
// await 的两种等待对象;
function promiseObj() {return new Promise((resolve,reject) => {setTimeout(resolve,1000,'promise!')
    })
}
function otherObj() {setTimeout(()=>console.log('otherObj!'),2000)
    // 或者是一个表达式等任何非 promise 对象
}

async function awaitDemo() {await otherObj();
    console.log('other!');
    let result = await promiseObj();
    console.log(result);
    console.log('promiseObj!')
}
awaitDemo();
// other! 立即执行
// promise!1s 后执行
// promiseObj!紧跟着上条执行
// otherObj!2s 后执行 
// 异步等待的错误处理;
function sleep(second) {return new Promise((resolve,reject) => {setTimeout(() => {reject('want to sleep~');
        },second)
    })
}

async function errorDemo() {let result = await sleep(2000);
    console.log(result);
    // Uncaught (in promise) want to sleep~
}

async function correctDemo() {
    try {let result = await sleep(2000);
        console.log(result);
    } catch(err) {console.log(err);
        // want to sleep~
    }
}
// 异步等待的并行处理;
function sleep(second) {return new Promise((resolve,reject) => {setTimeout(() => {resolve('done!' + Math.random());
        },second);
    })
}

async function bugDemo() {await sleep(1000);
    await sleep(2000);
    await sleep(3000);
    console.log('clear the loading~');
}

async function correctDemo() {let p1 = sleep(1000);
    let p2 = sleep(2000);
    let p3 = sleep(3000);
    await Promise.all([p1,p2,p3]);
    console.log('clear the loading~');
}

bugDemo(); // 6s 后输出 clear the loading~
correctDemo(); // 3s 后输出 clear the loading~

promise 和 async-await 的关系

  • async-await 只是 promise 的语法糖;
  • async-await 简化了 promise 的实现;
// 需求:以请求 1 的结果作为参数,发出请求 2
function request(second,param) {return new Promise((resolve,reject) => {setTimeout(resolve,second,param)
    })
}
// promise 实现
function promiseFunc() {
    let result1,result2,result3;
    request(2000,'req01').then(res => {
        result1 = res;
        return request(1000,'req02' + res)
    })
    .then(res => {
        result2 = res;
        return request(500,'req03' + res);
    })
    .then(res => {result3 = res;})
    .finally(() => {
        console.log(`
            ${result1}
            ${result2}
            ${result3}
        `)
    })
}
// async-await 实现
async function asyncFunc() {let result1 = await request(2000,'req01');
    let result2 = await request(1000,'req02' + result1);
    let result3 = await request(500,'req03' + result2);
    console.log(`
        ${result1}
        ${result2}
        ${result3}
    `);
}
  • async-await 的本质上还是 promise;
// 见上面 Promise.all 那个例子 
退出移动版