一、async/await:Promise+Generator的“语法糖”
1、async
作用:对函数的修饰
代码:async function xx(){ }
- 让函数的返回值自动变为promise实例
- 函数执行报错,则返回状态是rejected,值是报错原因的实例
- 如果执行不报错,再看返回值
- 返回值是新的实例,则以自己返回的promise实例为主
- 其他情况:都返回一个状态是fulfilled,值是返回值的实例;函数没有返回值,则返回状态是fulfilled,值是undefined
- 可以在函数中使用await
2、await
- 作用:可以监听promise的实例状态,从而决定去做啥事 -> let xxx = await [promise实例];
- 必须出现在一个经过async修饰的函数中
- await后边需要跟一个promise实例【如果不是promise实例浏览器也会把其变为实例】
await 14 => await Promise.resolve(14); - await会“等待”后边实例的状态为“成功”时,再把“当前上下位”中 await“下边”的代码执行! xxx就是实例状态为成功的返回结果
- 如果await后边的实例状态是“失败”,则下边代码不会执行(控制台会爆红,但是不影响其他代码执行!!!)
- 我们是基于try/catch实现对await后边实例为失败态的处理,避免爆红。
// 需求:设置三个定时器{2000,1000,3000},类似于ajax串行(第一个定时器触发后才能设置第二个...)
//回调地狱
setTimeout(() => {
console.log('第一个定时器触发执行');
setTimeout(() => {
console.log('第二个定时器触发执行');
setTimeout(() => {
console.log('第三个定时器触发执行');
}, 3000);
}, 1000);
}, 2000);
//async实现
const sleep = (interval = 1000) => {
return new Promise(resolve => {
setTimeout(() => {
resolve();
}, interval);
});
};
(async function(){
await sleep(2000);
console.log("第一个定时器触发执行");
await sleep(1000);
console.log('第二个定时器触发执行');
await sleep(3000);
console.log("第三个定时器触发执行");
})()
//以后写法
const handler = async () => {
await sleep(2000);
console.log('第一个定时器触发执行');
await sleep(1000);
console.log('第二个定时器触发执行');
await sleep(3000);
console.log('第三个定时器触发执行');
};
handler().then(() => {
console.log('当函数内部所有await都处理完,而且对应的实例都是fulfilled,才会让handler执行的返回值是成功的promise实例!');
}).catch(() => {
console.log('代码执行报错,或者其中某个await后面的实例是失败的,则直接让handler返回值也是失败的');
});
二、Promise & async/await 中的同步异步机制
1、同步
- 在新建promise实例时executor函数的立即执行
new Promise(resolve=>{
//executor函数会被立即执行【同步】:这里一般是管理异步编程代码,当异步结束,基于resolve/reject执行,控制实例状态的成功或者失败...
console.log(1);
})
console.log(2);
- Promise.resolve()/reject() 执行时会立即修改实例状态和值
let p1 = new Promise(resolve=>{
resolve(100); //resolve/reject执行会立即修改实例状态和值【同步】
// reject();
})
console.log(p1); //fulfilled->100
- 遇到await
- 把await后边的东西进行处理【同步】,获取一个promise实例\
- 然后把当前上下文中,await下面的代码设置为“异步的微任务”\
- 进入WebAPI中监听,当await后边的实例是成功的,再挪至EventQueue中排队等着
2、异步
- then方法都是异步微任务
//执行THEN的时候,此时不知道p1实例的状态
// + 把 onfulfilled & onrejected 存储到PROMISE内部的集合中
// p1.then(onfulfilled,onrejected) 【异步】
// + 如果此时已知p1的实例状态(不是pending),会根据状态去执行onfulfilled/onrejected;
// + 但并不会立即执行,而是创建一个“异步的微任务”
// + 进入到WebAPI中去监听,但是此时已经知道状态是成功的,则直接再挪至EventQueue中去排队
// + 当同步代码执行完,主线程空闲下来了,再去EventQueue中查找
p1.then(value=>{
console.log('成功',value);
},reason=>{
console.log('失败',reason);
});
console.log(111);
let p1 = new Promise(resolve => {
setTimeout(() => {
/!*
立即修改实例的状态和值「同步」
通知之前在集合中存储的方法执行「异步微任务」
+ 把存储的方法扔到WebAPI中去监听,但是发现实例状态已经是成功了,则挪至到EventQueue中排队等着
+ 把此上下文中剩下的代码执行完,再去获取这个异步任务执行
*!/
resolve(100);
console.log(222, p1);
}, 2000);
});
// console.log(p1); //pending & undefined
/!*
执行THEN的时候,此时不知道p1实例的状态
+ 把 onfulfilled & onrejected 存储到PROMISE内部的集合中
*!/
p1.then(value => {
console.log('成功:', value);
});
console.log(111);