同步与异步
同步(Synchronous)编程
特点
- 代码按顺序执行,一行完成后才执行下一行
- 阻塞式执行,后续代码必须等待当前操作完成
- 适用于简单、快速的操作
示例:
console.log("第一步");
console.log("第二步"); // 必须等待第一步完成
console.log("第三步"); // 必须等待第二步完成
异步(Asynchronous)编程
特点
- 代码不按书写顺序执行
- 非阻塞式执行,后续代码不必等待当前操作完成
- 适用于耗时操作(网络请求、文件读写等)
示例:
console.log("第一步");
setTimeout(() => {
console.log("第二步"); // 会在最后执行
}, 1000);
console.log("第三步"); // 不会等待setTimeout
Promise 介绍
基本概念
Promise
- 表示一个异步操作的最终完成(或失败)及其结果值
- 三种状态: pending(等待)、fulfilled(已完成)、rejected(已拒绝)
- 一旦状态改变就不会再变(从
pending
变为fulfilled
或rejected
)
基本用法
创建Promise
const myPromise = new Promise((resolve, reject) => {
// 异步操作
if (/* 操作成功 */) {
resolve("成功结果");
} else {
reject("失败原因");
}
});
使用Promise
myPromise
.then(result => {
console.log("成功:", result);
})
.catch(error => {
console.error("失败:", error);
})
.finally(() => {
console.log("无论成功失败都会执行");
});
链式调用
链式调用
- then()方法返回一个新的Promise
- 可以连续调用多个then()
示例:
fetchData()
.then(data => processData(data))
.then(processed => saveData(processed))
.then(() => console.log("全部完成"))
.catch(err => console.error("出错:", err));
静态方法
Promise.all()
等待所有Promise完成,如果有一个失败,立即拒绝
Promise.all([promise1, promise2, promise3])
.then(values => {
console.log(values); // [result1, result2, result3]
});
Promise.race()
返回最先完成(无论成功失败)的Promise结果
Promise.race([promise1, promise2])
.then(value => {
console.log(value); // 最先完成的promise的结果
});
Promise.allSettled()
等待所有Promise完成,无论成功失败
Promise.allSettled([promise1, promise2])
.then(results => {
results.forEach(result => {
if (result.status === "fulfilled") {
console.log("成功:", result.value);
} else {
console.log("失败:", result.reason);
}
});
});
async/await (基于Promise的语法糖)
特点
- 使异步代码看起来像同步代码
- async函数总是返回Promise
- await只能在async函数中使用
示例:
async function fetchData() {
try {
const response = await fetch('api/data');
const data = await response.json();
console.log(data);
return data;
} catch (error) {
console.error("出错:", error);
throw error;
}
}
fetchData().then(data => {
console.log("最终数据:", data);
});
Promise 常见使用场景
- AJAX/fetch请求
- 定时器操作
- 文件读取(在Node.js中)
- 数据库操作
- 任何需要等待的操作
Promise 最佳实践
- 总是处理错误(.catch或try/catch)
- 避免Promise嵌套(使用链式调用)
- 在async函数中合理使用await
- 为Promise函数添加有意义的名称
- 考虑使用Promise.all优化多个并行请求