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代码块之中。