探究async/await

async是‘异步’的简写,async声明一个function是异步的,而await用于等待一个异步方法执行完成,await只能出现在async函数中。

async await和generator的写法很像,就是将 Generator 函数的星号(*)替换成 async,将 yield 替换成await

但async 函数对 Generator 函数做了改进:

1、内置执行器:Generator函数的执行必须靠执行器,所以才有了 co 函数库,而 async 函数自带执行器.也就是说,async 函数的执行,与普通函数一模一样。

2、更好的语义:async 和 await,比起星号和 yield,语义更清楚了。async 表示函数里有异步操作,await 表示紧跟在后面的表达式需要等待结果。

3、更广的适用性: co 函数库约定,yield 命令后面只能是 Thunk 函数或 Promise 对象,而 async 函数的 await 命令后面,可以跟 Promise 对象和原始类型的值(数值、字符串和布尔值,但这时等同于同步操作)

  • async作用

async负责返回一个Promise对象,如果在async函数中return一个直接量,async会将这个直接量用Promise.resolve()封装成一个Promise对象,如果async函数没有返回值。它会返回Promise.resolve(undefine)。

  • await的作用

一般的都使用await去等待一个async函数完成,不过按语法说明,await等待的是一个表达式,这个表达式的计算结果是Promise对象或者其他值,所以啊await后面可以接收Promise对象或者直接量。

如果await等到的不是一个Promise对象,那跟着的表达式的计算结果就是要等的东西,如果是一个Promise对象,awiait会阻塞后面的的代码,直到promise对象resolve,得到resolve的值作为await表达式的运算接结果。

注意点: 只要其中一个Promise对象变为reject状态,那么整个async函数都会中断操作。如果状态是resolve,那么他的返回值则会变成resolve的值, 所以使用await时 最好把await 放入try{}catch{}中

  • async/await的深入探究

async/await技术背后的秘密其实是Promise和生成器的应用,再往底层就是微任务和协程应用(生成器是协程的一种实现方式。

协程:协程是一种比线程更加轻量级的存在,一种线程上可以存在多个协程,但线程上同一时刻只能运行一个协程,比如当前执行的是协程A,如果要去启动协程B,就要让协程A把线程的控制权交给协程B,这就实现了A暂停执行,B恢复执行。同样的也可以从B协程启动A协程。

通过具体的例子来了解一下。

async function fun(){
    console.log(1);
    let a=await 'await';
    console.log(a);
    console.log(3);
}
console.log(0);
let aa= fun();
console.log(aa)
console.log(4);
  • 首先执行console.log(0)这个语句,打印0。、
  • 然后执行fun函数,因为这个函数被async标记,所以js引擎会保存当前的调用栈,而去执行fun函数中语句,所以首先会执行console.log(1)
  • 接下来会执行await语句,当执行await "await"时,会自动创建一个Promise对象,最终将resolve的值返回a
let promise=new Promise((resolve,reject)=>{
	resolve('await');
})
  • js引擎暂停当前协程的执行,将主线程的控制权交给父协程执行,同时会将async创建的promise对象返回给父协程,这里传给了aa
  • 接下来执行console.log(aa)和console.log(4),然后主协程将主线程的控制权交给fun协程,最终就会执行console.log(a) console.log(3),执行完成之后将控制权还给父协程。
    在这里插入图片描述
  • await后面的参数

awiat后面可以跟任何js表达式,如果awiat后面跟着的是Promise对象则会等待函数执行完成再去执行下面的代码,如果跟着的是正常的表达式则会立即执行。

后面是Promise对象

function fun(time) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve("我是Promise");
        }, time);
    })
}
async function fuc() {
    let result = await fun(2000);
    console.log("123")
    console.log(result);
    console.log("456")
}
fuc();//先回等待两秒,两秒后依次打印123、我是Promise、456

后面是正常表达式

function fun(time) {
    console.log("我是js表达式");
    setTimeout(() => {
         console.log('1');
    }, time);
    return 2;
}
async function fuc() {
    let result = await fun(2000);
    console.log("123")
    console.log(result);
    console.log("456")
}
fuc();//依次输出 "我是js表达式"、123、2 456、1
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值