async函数 -- 异步函数

async函数 – 异步函数

作用

  • ES2017推出的一种新的处理异步请求方法,是generator的语法糖(generator的优化),可以用来轻松定义异步函数

对比generator

  1. async 取代 *

  2. await 取代 yield

  3. async不需要自己手动移动指针,它会自动执行,如果在某个阶段执行失败则会终止执行后面的任务,而generator需要手动调用next()一步步执行

  4. await右边是表达式或语句,如果它返回不是Promise对象会调用Promise.resolve(),把这个值转换成状态为re,如果是promise对象,返回resolve()语句执行时传入的实参

         async function foo1(){
            let a = await 1+3;
            let b = await add(2,4);
            console.log(a); //4
            console.log(b); //6
        }

        async function foo2(){
            let a = await Promise.resolve('1');
            let b = await Promise.resolve('2');
            console.log(a); //1
            console.log(b); //2
        }
        // await执行的是异步任务,他会在主线程后执行  
        foo1();
        foo2();
        //await执行的异步操作,会先输出3
        console.log(3);

        // 3
        // 4
        // 6
        // 1
        // 2             

foo1()里的 4, 6 都会先转换为Promise对象,并且把返回7与对应promise对象调用resolved()回调函数时传入的参数相同的值(有点绕~)

    async function foo3(){
        let a = await 1+3;
        return a;
    }
    async function foo3(){
        let a = 1+3;
        return a;
    }

    foo3();
    foo4();
  • async 函数始终返回一个promise对象,就算不是也会包装成一个promise对象,并且该对象的状态是fulfilled
     
        async function foo3() {
            return await 1 + 3; // 尝试解包promise对象, 返回resolve传入的实参
        }
        async function foo4() {
            return 1 + 3;  // 直接返回的话不会解包,返回Promise对象
        }
        async function foo5() {
            console.log(1 + 3);  // 直接返回的话不会解包,返回Promise对象
        }

        console.log(foo3()); // Promise{fulfilled: 4}
        console.log(foo4());   // Promise{fulfilled: 4}
        console.log(foo5()); // Promise{fulfilled: undefined}

foo3() 里的await在return命令中,按上面的foo1()的道理应该返回一个数值4,但是返回的确实Promise对象,为啥?其实这里没有矛盾,而是里面有两步操作,await返回的确实是数值4,但是aysnc返回的必须是一个Promise对象,所以又会把数值4封装成一个Promise对象。

foo5()没有返回值,所以PromiseResult为 undefined

  • aysnc 只是一个标识符,真正起作用的应该是 await,如果一个异步函数没有await,他跟同步函数没有啥区别
  • await 不仅仅是等待一个值那么简单,当js运行时遇到了await关键字,会记录停止的位置,等到值求得后,js运行时会向消息队列推送一个任务,这个任务会恢复异步函数的执行
  • 即使 await 后面跟着一个立即可用的值,函数的其余部分也会被异步求值。
async function foo() {
    console.log(2);
    await null;
    console.log(4);
}
console.log(1);
foo();
console.log(3);

// 1
// 2
// 3
// 4

console.log(4)应该是立即执行函数,但是却在console.log(3)后面执行,这正是前面有await命令,是的console.log(4)变成了异步任务

  • 上面函数的执行过程

// (1) 打印 1;
// (2) 调用异步函数 foo();
// (3)(在 foo()中)打印 2;
// (4)(在 foo()中)await 关键字暂停执行,为立即可用的值 null 向消息队列中添加一个任务;
// (5) foo()退出;
// (6) 打印 3;
// (7) 同步线程的代码执行完毕;
// (8) JavaScript 运行时从消息队列中取出任务,恢复异步函数执行;
// (9)(在 foo()中)恢复执行,await 取得 null 值(这里并没有使用);
// (10)(在 foo()中)打印 4;
// (11) foo()返回。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值