按顺序:回调函数 → Promise → async/await,工作最常用,直接上手。
-
回调函数(最原始,缺点:回调地狱)
-
Promise(解决回调地狱,链式调用)
new Promise((resolve, reject) => {
//异步操作
//成功 resolve(数据)
// 失败 reject(错误)
})
.then((res) => {
//成功处理
})
.catch((err) => {
//失败处理
});
真实场景 封装定时器异步
function fn(msg, delay) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(msg);
}, delay);
});
}
链式调用
fn("第一步", "1000")
.then((res) => {
console.log(res);
return fn("第二步", 1000);
})
.then((res) => {
console.log(res);
return fn("第三步", 1000);
})
.then((res) => console.log(res));
常用静态方法
Promise.all([p1,p2,p3]):全部成功才成功(并行请求)
Promise.race([p1,p2]):谁先完成取谁
并行 2 个接口,同时发请求
Promise.all([fn("A", 1000), fn("B", 2000)]).then((res) => {
console.log(res, "Promise.all");
});
- async /await(终极写法,最舒服,项目必用)
async function 函数名(){
const 结果 = await Promise对象;
}
上面的定时器 用async/await 重写
function fnawait(msg, delay) {
return new Promise((resolve, reject) => {
setTimeout(() => resolve(msg), delay);
});
}
async function run() {
const r1 = await fnawait("1", 1000);
console.log(r1);
const r2 = await fnawait("2", 1000);
console.log(r2);
const r3 = await fnawait("3", 1000);
console.log(r3);
}
run();
捕获错误(try/catch)
async function runDetails() {
try {
const res = await fn("第一步", 1000);
console.log(res);
} catch (err) {
console.log("出错了", err);
}
}
runDetails();
一句话总结:
1.回调:嵌套地狱,不用
2.Promise:链式,解决嵌套
3.async/await 最简
完整代码:
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>练习</title>
</head>
<body>
<div id="content"></div>
<script>
console.log("--- JS 异步 从零讲(大白话 + 真实场景 + 可运行案例) ---");
//按顺序:回调函数 → Promise → async/await,工作最常用,直接上手。
//1. 回调函数(最原始,缺点:回调地狱)
// 2. Promise(解决回调地狱,链式调用)
new Promise((resolve, reject) => {
//异步操作
//成功 resolve(数据)
// 失败 reject(错误)
})
.then((res) => {
//成功处理
})
.catch((err) => {
//失败处理
});
//真实场景 封装定时器异步
function fn(msg, delay) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(msg);
}, delay);
});
}
// 链式调用
fn("第一步", "1000")
.then((res) => {
console.log(res);
return fn("第二步", 1000);
})
.then((res) => {
console.log(res);
return fn("第三步", 1000);
})
.then((res) => console.log(res));
// 常用静态方法
// Promise.all([p1,p2,p3]):全部成功才成功(并行请求)
// Promise.race([p1,p2]):谁先完成取谁
// 并行 2 个接口,同时发请求
Promise.all([fn("A", 1000), fn("B", 2000)]).then((res) => {
console.log(res, "Promise.all");
});
// 3. async /await(终极写法,最舒服,项目必用)
// async function 函数名(){
// const 结果 = await Promise对象;
// }
// 上面的定时器 用async/await 重写
function fnawait(msg, delay) {
return new Promise((resolve, reject) => {
setTimeout(() => resolve(msg), delay);
});
}
async function run() {
const r1 = await fnawait("1", 1000);
console.log(r1);
const r2 = await fnawait("2", 1000);
console.log(r2);
const r3 = await fnawait("3", 1000);
console.log(r3);
}
run();
// 捕获错误(try/catch)
async function runDetails() {
try {
const res = await fn("第一步", 1000);
console.log(res);
} catch (err) {
console.log("出错了", err);
}
}
runDetails();
// 一句话总结:
//1.回调:嵌套地狱,不用
//2.Promise:链式,解决嵌套
//3.async/await 最简
</script>
</body>
</html>