美文网首页
es6--async和await

es6--async和await

作者: 前端架构师陈龙威 | 来源:发表于2020-04-03 16:05 被阅读0次

    async 和 await被称为js异步的最终解决方案,那么我们来了解下:
    async:异步方法,

    async function getNum(num) {
        return num++
    }
    getNum(1);
    
    // 很平常的使用,但async返回的Promise()对象,不管里面有没有return,只是return的话在then()方法中能取到return的值,如果return,那么就是Promise.resolve(返回值),如果没有返回值,那么就是Promise.resolve()
    

    await:等待执行完毕

    // await只支持在async的方法中使用
    // await后面可以跟任何js表达式
    // await后面跟的是Promise对象,则会造成async函数的停止直到它后面跟的Promise对象的状态被resovle或者reject
    // await后面跟的是正常表达式则立即执行
    
    
    // 一个比较简单的例子
    function normalFn() {
        console.log('normal')
    }
    function promiseFn(time) {
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve('promise sleep ' + time + ' ms')
            }, time)
        })
    }
    async function handleFn() {
        console.log('start');
        let a = await normalFn();
        console.log(a);
        let b = await promiseFn(2000);
        console.log(b);
    }
    
    // 执行结果为:
    'start'
    'normal'
    undefined // 因为a = normalFn(),而非a = function normal() {},方法执行后没有任何返回,所以就undefined了,如果你安排一个返回值,那么就不会undefined了,你可以在normalFn方法中试试在添加个return,那样就不会undefined了
    Promise() // handleFn()方法返回的一个Promise对象
    'promise sleep 2000 ms' // 因为setTimeout归属于宏任务,所以在微任务都执行完毕之后才进行执行,你也可以试试0s,它依旧是最后一个才出现
    
    // 然后我们举例一个入门级的例子: 
    // 例子1:我们有个方法,需要统计3次计算的总和,但是这3次计算分别都非常耗时
    function getNum(time) {
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve(Math.floor(Math.random()*10))
            }, time)
        })
    }
    async function getSum() {
        let num1 = await getNum(1000);
        let num2 = await getNum(2000);
        let num3 = await getNum(3000);
        console.log(11); // 会发现11和下面的内容是同时出现的,说明await是等到执行结束或者又返回才进行下一步
        console.log(num1 + ':' + num2 + ':' + num3)
    }
    getSum();
    
    // 例子2:我们有个方法,里面依次循环计算3次,且每次计算都需要上一轮的结果作为后一轮的数据
    function getResult(param) {
         return new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve(param)
            }, 2000)
        })
    }
    async function getStr() {
        let str1 = await getResult('str1');
        let str2 = await getResult(str1 + 'str2');
        let str3 = await getResult(str2 + 'str3');
        console.log(str3);
    }
    getStr();
    
    // 接着我们来了解async如何接受错误
    // 一般都知道用reject,但是怎么接收呢?
    function errHandle() {
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                reject('error handle by advisedly');
            }, 1000); 
        })
    }
    async function correctFn() {
        let msg = await errHandle();
        console.log(msg);
    }
    correctFn(); // 这样并不能正确的拿到报错信息
    
    // 我们需要这么改:
    async function correctFn() {
        try {
            let msg = await errHandle();
            console.log(msg);
        } catch(err) {
            console.log(err); // 这里接收了reject
        }
    }
    // 有人会想这么改:虽然也能抓到,但是个人不太喜欢,因为有种又陷入到无限Promise的感觉
    correctFn().catch(e => {console.log('er'+e)})
    
    // 常用实例:
    // 多个请求,所有请求都结束之后才取消加载动画
    function request(time) {
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve('请求成功');
            }, time)
        })
    }
    // 这是错误的写法,会阻塞异步请求
    async function initFn() {
        let req1 = await request(1000);
        let req2 = await request(1000);
        let req3 = await request(1000);
        console.log('加载动画取消ing'); 
    }
    // 这才是正确操作
    async function initFn() {
        let req1 = request(1000);
        let req2 = request(1000);
        let req3 = request(1000);
        await Promise.all([req1, req2, req3]);
        console.log('加载动画取消ing');
    }
    
    // 注意点:await要求在async方法中,且不能被其他方法包裹
    
    // 这样是无法正确输出的。
    // 报错提示:Uncaught SyntaxError: await is only valid in async function
    async function demo() {
        let arr = [1,2,3,4,5];
        arr.forEach(item => {
            await console.log(item)
        })
    }
    
    // 正确写法:
    async function demo() {
        let arr = [1,2,3,4,5];
        for (let i=0; i<arr.length; i++) {
            await console.log(arr[i])
        }
    }
    

    相关文章

      网友评论

          本文标题:es6--async和await

          本文链接:https://www.haomeiwen.com/subject/rvptphtx.html