执行顺序遵循以下核心规则:
同步代码 > 微任务(Promise、await后代码)>宏任务(如setTimeout)
**async/await与Promise的含义: **Promise:用于替代传统的回调地狱 Promise是一个对象,表示异步操作的最终完成(或失败)及其结果值。它有三种状态:
- pending:初始状态,既不是成功也不是失败。
- fulfilled:操作成功完成。
- rejected:操作失败。
一旦状态变为 fulfilled 或 rejected,就称为 resolved(已解决),且状态不可再变。
只能从pending变成fulfilled 或者rejected状态,不能变成pending
js
new Promise((resolve, reject) => {
if (success) {
resolve("操作成功"); // 成功时调用 resolve
} else {
reject(new Error("操作失败")); // 失败时调用 reject
}
});
链式调用:then ()、catch ()、finally ()
Promise 通过 .then()
和 .catch()
处理结果,支持链式调用
catch()可以监听前面任一过程的错误
js
promise.then((value) => {
console.log(value); // 输出:操作成功
}).catch((error) => {
console.error(error); // 操作失败时执行
}) .finally(() =>
console.log("无论如何都会执行")
);
链式调用的返回值
.then() 和 .catch() 会返回一个新的 Promise,因此可以链式调用。
如果返回值是普通值(非 Promise),则会被包装为 Promise.resolve(返回值)。
如果返回值是 Promise,则会等待该 Promise 解决,并将其结果传递给下一个 .then()。
js
promise
.then((value) => {
return value + "!"; // 返回普通值
})
.then((newValue) => {
return new Promise((resolve) => {
setTimeout(() => resolve(newValue + " again"), 1000); // 返回 Promise
});
})
.then((finalValue) => console.log(finalValue)); // 输出:操作成功! again
除此之外还有:Promise.all ()、Promise.race ()、Promise.allSettled()、Promise.any() Promise.all ():并行执行多个 Promise,返回一个新的 Promise,当所有 Promise 都成功时才成功,否则失败。
Promise.race (): 并行执行多个 Promise,返回一个新的 Promise,第一个解决(无论成功或失败)的 Promise 的结果就是最终结果。
js
const fastPromise = new Promise((resolve) => setTimeout(() => resolve("快的 Promise"), 500));
const slowPromise = new Promise((resolve) => setTimeout(() => resolve("慢的 Promise"), 2000));
Promise.race([fastPromise, slowPromise])
.then((value) => console.log(value)) // 输出:快的 Promise
.catch((error) => console.error(error));
Promise.allSettled(): 返回一个 Promise,当所有输入的 Promise 都已解决(无论成功或失败)时,返回包含每个 Promise 结果的数组。
js
Promise.allSettled([promise1, promise2])
.then((results) => {
results.forEach((result) => {
if (result.status === "fulfilled") {
console.log("成功:", result.value);
} else {
console.log("失败:", result.reason);
}
});
});
Promise.any(): 返回一个 Promise,只要有一个输入的 Promise 成功,就返回该 Promise 的结果;只有当所有 Promise 都失败时才失败。
js
Promise.any([promise1, promise2])
.then((value) => console.log("至少有一个成功:", value))
.catch((error) => console.error("所有都失败:", error));
async 函数
async/await 是 ES2017(ES8)引入的语法糖,用于简化 Promise 的使用,让异步代码看起来更像传统的同步代码。它基于 Promise 实现,本质上是 Promise 的语法增强。
定义:使用 async 关键字声明的函数,自动返回一个 Promise对象,表示函数内部有异步操作。 返回值:函数内部的返回值会被包装为 Promise.resolve(返回值)。
js
async function fn1() {
return 123
}
function fn2() {
return 123
}
console.log("fn1",fn1())
/*输出结果:
fn1 Promise {<fulfilled>: 123}
[[Prototype]]:Promise
[[PromiseState]]:"fulfilled"
[[PromiseResult]]: 123
*/
console.log("fn2",fn2())
/*输出结果:
fn2 123
*/
await 表达式
- 作用 :暂停
async
函数的执行,等待 Promise 解决(resolved),并返回其结果。 - 语法限制 :只能在
async
函数内部使用。
await等的是右侧「表达式」的结果,执行顺序从右--》左
也就是说await同行后面的的代码一旦完成就把后续代码放进微队列,后面没有代码了那么对应的async进入微队列
await等待有两种结果:
- 如果await后面是不是promise对象,那么await会阻塞后面的代码,先执行async函数外面的同步代码,同步代码执行完毕,再回到async内部,把这个非promise的东西,作为await表达式的结果。
- 如果await后面是promise对象,那么他会在async外部的同步代码执行完毕之后等到promise对象fulfilled,然后把resolve的参数作为await表达式的运行结果。
例题理解:
小提示:Promise.resolve()是同步执行的方法,后面可以跟一个值或者函数,会立即返回一个已解决的状态(resolved)
await 42 或函数;类似于Promise.resolve(42或函数) 是立即执行的
Promise.resolve().then就是微任务
(1)这个例子只是我个人读代码顺序
js
async function asy1() {
console.log("asy1 start")
await asy2()
console.log("asy1 end")
}
const asy2 = async ()=>{
console.log("asy2 start")
//setTimeout(函数,时间)在多少时间后,把函数内容放到宏队列
await setTimeout(()=>{
Promise.resolve().then(()=>{
console.log("asy2 setTimeout Promise.resolve().then")
})
console.log("asy2 setTimeout")
},10)
console.log("asy2 end")
}
const asy3 = async ()=>{
console.log("asy3 start")
Promise.resolve().then(()=>{
console.log("asy3 Promise.resolve().then")
})
console.log("asy3 end")
}
asy1();
console.log("script")
asy3();
代码梳理:从上往下读,声明了三个函数,调用函数asy1、打印语句、调用函数asy2;
此时的同步函数(从上到下依次执行):
asy1();
console.log("script")
asy3();
开始执行,进入asy1函数
js
async function asy1() {
console.log("asy1 start") //同步代码
await asy2() //同步代码
console.log("asy1 end")
}
控制台输出:asy1 start
进入asy2函数
js
const asy2 = async ()=>{
console.log("asy2 start") //同步代码
//setTimeout(函数,时间)在多少时间后,把函数内容放到宏队列
await setTimeout(()=>{ //同步代码
Promise.resolve().then(()=>{
console.log("asy2 setTimeout Promise.resolve().then")
})
console.log("asy2 setTimeout")
},10)
console.log("asy2 end") //同步代码
}
控制台输出:asy2 start
等待执行的任务:
宏队列:setTimeout【10ms后执行】
微队列:等待asy2完成 此时asy2还在等待,asy1暂时执行完毕开始执行console.log("script")
控制台输出:script 打印语句执行完毕,开始调用asy3
js
const asy3 = async ()=>{
console.log("asy3 start") //同步代码
Promise.resolve().then(()=>{
console.log("asy3 Promise.resolve().then")
}) //放入微队列,稍后异步执行
console.log("asy3 end") //同步代码
}
控制台输出:asy3 start asy3 end
等待执行的任务: 宏队列:setTimeout【10后执行】 微队列: ①等待asy2完成执行console.log("asy2 end") ②asy3的Promise.resolve().then
此时第一层的同步代码执行完毕,接下来先清空微队列,asy2完成后,输出打印结果asy1的打印语句进入微队列等待执行
控制台输出:asy2 end
等待执行的任务: 宏队列:setTimeout【10后执行】 微队列: ①asy3的Promise.resolve().then ②console.log("asy1 end")
依次执行微队列,控制台输出:
asy3 Promise.resolve().then
asy1 end
微队列执行完毕,开始执行宏队列,也就是执行asy2 的这段代码,此时Promise.resolve().then和打印语句都是同步代码,Promise里面的打印语句进入微队列
js
await setTimeout(()=>{
Promise.resolve().then(()=>{
console.log("asy2 setTimeout Promise.resolve().then")
})
console.log("asy2 setTimeout")
},10)
此时控制台打印: asy2 setTimeout
等待执行的任务: 微队列:console.log("asy2 setTimeout Promise.resolve().then")
执行最后一个微队列,控制台输出:
asy2 setTimeout Promise.resolve().then
最终控制台的输出结果:

(2)首先分析代码中的同步、宏任务、微任务
js
console.log("---------------- start");//同步代码
async function async1() {
console.log("async1 start");//同步代码
await async2();//同步代码
console.log("async1 end");//微任务
}
async function async2() {
console.log("async2 -----");//同步代码
}
async1();//同步代码
setTimeout(function(){
console.log("setTimeout");
},0);//宏任务
new Promise((resolve)=>{
console.log("Peomise");//同步代码
resolve();
})
.then(function(){
console.log("Peomise.then");//微任务
})
.then(function(){
console.log("Peomise.then.then");//微任务
});
console.log("---------------- end");//同步代码
从上往下读取代码,先执行同步代码
此时控制台输出:---------------- start
往下读是两个函数,然后是调用async1();开始执行async1的代码
js
async function async1() {
console.log("async1 start");//同步代码
await async2();//同步代码
console.log("async1 end");//微任务
}
此时控制台输出:async1 start
等待async2执行,打印语句进入微任务
微任务:async1的console.log("async1 end");
js
async function async2() {
console.log("async2 -----");//同步代码
}
此时控制台输出:async2 -----
async1的调用暂时执行完毕,接下来是setTimeout是宏任务,在往下读立即执行Promise的同步代码,其中.then是微任务进入任务队列
宏任务:setTimeout(function() 微任务:①async1的console.log("async1 end"); ②Promise.then ③Promise.then.then
此时控制台输出:Peomise
然后执行最后一行代码console.log("---------------- end");//同步代码
此时控制台输出:---------------- end
同步代码执行完毕
接下来执行微任务
此时控制台输出:async1 end Promise.then Promise.then.then
微任务执行完毕,开始宏任务:
此时控制台输出:setTimeout
最终输出结果:
