美文网首页
async/await你是否真的明白

async/await你是否真的明白

作者: 李贵功 | 来源:发表于2019-06-03 22:44 被阅读0次

    async 函数总是返回一个 Promise 对象,所以你可以用then去处理结果

    1. async函数中返回的是promise

     function sleep () {
       return new Promise(resolve => {setTimeout(resolve,3000,2)})
     }
     async function f1() {
       return await sleep()
     }
    
    console.log(f1());   // 见下图
    f1().then(res => console.log(res))  // 2
    
    结果

    2. async函数中返回的不是promise

    async function f1() {
     return 'hello world'
    }
    
    console.log(f1()); // 见下图
    f1().then(res => console.log(res)) // 'helle world'
    

    从结果中可以看到async函数返回的是一个promise对象,如果在函数中 return 一个直接量,async 会把这个直接量通过 Promise.resolve() 封装成 Promise 对象


    image

    3. 如果asyn函数没有返回值

    async function foo() {
      console.log(1)
    }
    
    console.log(foo());
    
    image

    async 函数返回的 Promise 对象,必须等到内部所有的 await 命令的 Promise 对象执行完,才会发生状态改变

    也就是说,只有当 async 函数内部的异步操作都执行完,才会执行 then 方法的回调。

    const delay = timeout => new Promise(resolve=> setTimeout(resolve, timeout));
    async function f(){
        await delay(1000);
        await delay(2000);
        await delay(3000);
        return 'done';
    }
    
    f().then(v => console.log(v)); // 等待6s后才输出 'done'
    

    正常情况下,await 命令后面跟着的是 Promise ,如果不是的话,也会被转换成一个 立即 resolve 的 Promise

    async function  f() {
        return await 1
    };
    f().then( (v) => console.log(v)) // 1
    

    如果返回的是 reject 的状态,则会被 catch 方法捕获。


    Async 函数的错误处理

    // 正确的写法
    // 模拟ajax的函数
    function ajax () {
        return new Promise((resolve, reject) => setTimeout(reject,2000,1))
    }
    async function correct() {
        let a;
        try {
            a = await ajax()
        } catch (error) {
            throw new Error('ajax接口错误:'+error)
        }
        console.log(a)
        console.log(465)
    }
    
    correct()
    

    他会阻止后面的代码继续执行

    image

    await做了什么处理

    从字面意思上看await就是等待,await 等待的是一个表达式,这个表达式的返回值可以是一个promise对象也可以是其他值。

    很多人以为await会一直等待之后的表达式执行完之后才会继续执行后面的代码,实际上await是一个让出线程的标志。await后面的紧跟(函数)会先执行一遍,这里说的await后面的函数,是紧跟在await后的,然后就会跳出整个async函数来执行后面js栈(后面会详述)的代码。等本轮事件循环执行完了之后又会跳回到async函数中等待await
    后面表达式的返回值,如果返回值为非promise则继续执行async函数后面的代码,否则将返回的promise放入promise队列(Promise的Job Queue)

    async/await 执行顺序

    function testSometing() {
        console.log("执行testSometing");
        return "testSometing";
    }
    
    async function testAsync() {
        console.log("执行testAsync");
        return Promise.resolve("hello async");
    }
    
    async function test() {
        console.log("test start...");
        const v1 = await testSometing();//关键点1
        console.log(v1);
        const v2 = await testAsync();
        console.log(v2);
        console.log(v1, v2);
    }
    
    test();
    
    var promise = new Promise((resolve)=> { console.log("promise start.."); resolve("promise");});//关键点2
    promise.then((val)=> console.log(val));
    
    console.log("test end...")
    

    结果:

    test start...
    执行testSometing
    promise start..
    test end...
    testSometing
    执行testAsync
    promise
    hello async
    testSometing hello async
    

    这个就是在async/await 函数之后js的执行顺序,我们再看一个列子把testSometing函数前面加上async

    async function testSometing() {
        console.log("执行testSometing");
        return "testSometing";
    }
    
    async function testAsync() {
        console.log("执行testAsync");
        return Promise.resolve("hello async");
    }
    
    async function test() {
        console.log("test start...");
        const v1 = await testSometing();
        console.log(v1);
        const v2 = await testAsync();
        console.log(v2);
        console.log(v1, v2);
    }
    
    test();
    
    var promise = new Promise((resolve)=> { console.log("promise start.."); resolve("promise");});//3
    promise.then((val)=> console.log(val));
    
    console.log("test end...")
    

    结果:

    test start...
    执行testSometing
    promise start..
    test end...
    promise
    testSometing
    执行testAsync
    hello async
    testSometing hello async
    

    相关文章

      网友评论

          本文标题:async/await你是否真的明白

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