async await

1,203 阅读3分钟

async await

async函数是ES6的新语法;使得异步操作变得更加方便。 使用关键字async来表示,在函数内部使用await来表示异步。

async函数中如果没有await,那么和普通函数一样的; 一旦加了await;那么await下面的代码就是异步的;

当主任务队列中的任务执行完成,然后去等待队列先找到微任务,把微任务放到主任务队列执行,如果有多个微任务,按照执行的顺序依次执行;执行完成再去执行等待队列中的宏任务;

微任务 宏任务

微任务 宏任务: 这两个都是异步队列中的任务; 异步任务: setTimeout、setInterval、事件、promise的then、ajax、async await; 微任务: promise的then、async await、process.nextTick; 宏任务 : setTimeout、setInterval、ajax;

先执行微任务,再执行宏任务;

async函数

async函数是 Generator 函数的语法糖。 相较于 Generator,Async 函数的改进在于下面四点:

  • 内置执行器。Generator 函数的执行必须依靠执行器,而 Aysnc 函数自带执行器,调用方式跟普通函数的调用一样
  • 更好的语义。async 和 await 相较于 * 和 yield 更加语义化;
  • 更广的适用性。co 模块约定,yield 命令后面只能是 Thunk 函数或 Promise对象。而 async 函数的 await 命令后面则可以是 Promise 或者 原始类型的值(Number,string,boolean,但这时等同于同步操作);
  • 返回值是 Promise。async 函数返回值是 Promise 对象,比 Generator 函数返回的 Iterator 对象方便,可以直接使用 then() 方法进行调用

async函数自带执行器。async函数的执行,与普通函数执行一模一样;

function fn1() {
	console.log(200);
}
async function fn() {
	await fn1(); //同步
	console.log(100); //异步
}
console.log(fn()); //输出promise实例,且是pending状态;
fn().then(function(a){
	console.log(a); //输出undefined
})

async 返回一个promise的实例;默认是成功态; async函数内部return语句返回的值,会成为then方法回调函数的参数。

async function fn() {
	return 1;
}
console.log(fn());// async 返回一个promise的实例;默认是成功态;
//fn()的结果不受async function fn() {}函数中return的影响;fn()的结果永远都是promise实例;不然不能调用.then方法;
fn().then(function (a) { //由于fn()返回的是一个promise实例,所以可以调用.then方法;
	console.log(a); //1  //.then中的结果会受fn()中return结果的影响;
});
function fn1() {
// fn1函数中如果返回一个promise的实例,await下面的代码就是该promise的实例then中绑定函数中的代码;
	return new Promise(function (resolve,reject) {
		setTimeout(function () {
			console.log(300);
			resolve()
		},200)
	})
}
async  function fn() {
	await fn1();
	// 如果fn1返回一个promise的实例,那么这个await下面的代码当上面调用resolve才会执行;
	console.log(200); //这句代码受fn1函数中return的promise实例的结果的影响; 
}
fn().then(function () {
}).then(function () {
})

async 函数返回的 Promise 对象,必须等到内部所有的 await 命令的 Promise 对象执行完,才会发生状态改变 也就是说,只有当 async 函数内部的异步操作都执行完,才会执行 then 方法的回调。

async 函数多种形式

//函数声明
async function fn(){}

//函数表达式
let fn = async function(){}

//箭头函数
let fn = async () => {}

//对象的方法
let obj = { async fn(){} }
obj.fn().then(...)

//class的方法
class Storage {
	constructor() {
		this.cachePromise = caches.open('avatars');
}
async getAvatar(name) {
	const cache = await this.cachePromise;
	return cache.match(`/avatars/${name}.jpg`);
	}
}
const storage = new Storage();
storage.getAvatar('jake').then(…);

async函数的错误处理

如果 async 函数内部抛出异常,则会导致返回的 Promise 对象状态变为 reject 状态。抛出的错误而会被 catch 方法回调函数接收到。

如果await后面的异步操作出错,那么等同于async函数返回的 Promise 对象被reject。 防止出错的方法,也是将其放在try...catch代码块之中。