Async 函数
- 函数的返回值是
Promise对象 Promise对象的结果由async函数执行的返回值决定
// 未加 async 之前
function fn(){
return 1;
}
const result = fn();
console.log(result); // 1
// 加上 async 之后
function fn(){
return 1;
}
const result = fn();
console.log(result);
输出结果为 Promise 对象
// 想要拿到 result 的结果只能通过 then()
result.then(
value =>{ console.log('onResolved()', value) },
reason => { console.log('onRejected()', reason) }
)
这时输出结果为:onResolved() 1
Await 表达式
await表达式必须放在async函数里,否则会报错- 表达式右侧一般为
Promsie对象,但也可以是其他的值 - 如果表达式是
Promise,await返回的是Promise成功的值 - 如果表达式是其他的值,则直接将此值作为
await的返回值 - 如果
await的Promise失败就会抛出异常,需通过try...catch来捕获处理
宏队列
- 用来保存执行的宏任务(回调):
- 定时器回调
DOM事件回调Ajax回调
// 情景一:
function fn1(){
return new Promise((resolve, reject)=>{
setTimeout(()=>{
resolve(1);
},2000)
})
}
async function fn2(){
// await 右侧表达式为 Promise,得到的结果就是 Promise 成功的 value
const result = await fn1();
console.log(result )
}
fn2(); // 等待 2 秒后 输出 1
// 情景二:
function fn1(){
return 1;
}
async function fn2(){
// await 右侧表达式为非 Promise ,得到的结果就是它本身
const result = await fn1();
console.log(result)
}
fn2(); // 直接输出 2
// 情景三:
function fn1(){
return new Promise((resolve, reject)=>{
setTimeout(()=>{
reject(1);
},2000)
})
}
async function fn2(){
try{
// await 的 Promise 失败需要 `try...catch` 捕获来拿到错误信息,抛出异常也是如此
const result = await fn1();
}catch(error){
console.log(error)
}
}
fn2(); // 等待 2 秒后 输出 1
微队列
- 用来保存待执行的微任务(回调):
Promise回调MutationObserver回调
注意:
- JS引擎首先必须先执行所有的初始化的同步任务代码
- 每次准备取出第一个宏任务之前,都要将所有的微任务一个一个取出来执行
举 个 栗 子
setTimeout(() => {
console.log(1)
}, 0);
Promise.resolve(2).then(
value => { console.log(value ) }
)
输出顺序为:2 1
setTimeout是宏任务Promise是微任务,微任务执行先于宏任务即:每次准备取出第一个宏任务之前,都要将微任务逐个取出并执行。
setTimeout(() => {
console.log(1)
}, 0);
setTimeout(() => {
console.log(2)
}, 0);
Promise.resolve(3).then(
value => { console.log(value ) }
)
Promise.resolve(4).then(
value => { console.log(value ) }
)
输出顺序为:3 4 2 1
微任务执行先于宏任务,有多个同种任务时,按顺序依次执行。
setTimeout(() => {
console.log(1)
Promise.resolve(2).then(
value => { console.log(value ) }
)
}, 0);
Promise.resolve(3).then(
value => { console.log(value ) }
)
console.log(4);
输出顺序为:4 3 1 2
1、
JS引擎首先必须先执行所有的初始化同步任务代码即先输出 4
2、微任务执行先于宏任务即先输出 3
3、每次准备取出第一个宏任务之前,都要将微任务逐个取出并执行即输出 1 2
综上:执行顺序为:同步代码 =》微任务 =》 宏任务 =》宏任务里的微任务