Promise
是 JavaScript 中用于处理异步操作的一个对象,它表示一个异步操作的最终结果,可能是成功或失败,Promise
通常用于处理异步操作,比如从服务器获取数据 、读取文件 、定时任务 、用户操作等
基本的使用
js
const myPromise = new Promise((resolve, reject) => {
const success = true;
if(success) {
resolve("操作成功!");
} else {
reject("操作失败。");
}
});
myPromise
.then(result => console.log(result)) // 如果 Promise 成功
.catch(error => console.log(error)); // 如果 Promise 失败
常见的用法和示例
- 链式调用 (
then
)
Promise
支持链式调用,可以在一个 then
后接着另一个 then
,处理不同的异步操作。
js
new Promise((resolve, reject) => {
setTimeout(() => resolve("第一个操作成功!"), 1000);
})
.then(result => {
console.log(result); // 输出: 第一个操作成功!
return "第二个操作成功!";
})
.then(result => {
console.log(result); // 输出: 第二个操作成功!
});
- 多个 Promise 的并行执行 (
Promise.all
)
如果你有多个独立的异步操作,并且你希望它们并行执行,可以使用 Promise.all
,它会等到所有的 Promise 都完成后再继续执行。
js
const promise1 = new Promise(resolve => setTimeout(() => resolve("操作1完成"), 1000));
const promise2 = new Promise(resolve => setTimeout(() => resolve("操作2完成"), 2000));
Promise.all([promise1, promise2])
.then(results => {
console.log(results); // 输出: ["操作1完成", "操作2完成"]
});
- 处理单个 Promise 的异常 (
catch
)
catch
方法是用来捕捉 Promise
中的异常的,它可以让你在异步操作失败时处理错误。
js
new Promise((resolve, reject) => {
setTimeout(() => reject("操作失败!"), 1000);
})
.then(result => {
console.log(result);
})
.catch(error => {
console.log("捕获错误:", error); // 输出: 捕获错误: 操作失败!
});
- Promise 的竞态条件 (
Promise.race
)Promise.race
会返回第一个完成的 Promise,不管它是成功还是失败。
js
const promise1 = new Promise(resolve => setTimeout(() => resolve("操作1完成"), 2000));
const promise2 = new Promise(resolve => setTimeout(() => resolve("操作2完成"), 1000));
Promise.race([promise1, promise2])
.then(result => {
console.log(result); // 输出: 操作2完成
});
- 串联多个异步操作 (
async/await
)
async/await
是 Promise
的语法糖,使得异步操作看起来像是同步的。
js
async function run() {
try {
const result1 = await new Promise(resolve => setTimeout(() => resolve("操作1完成"), 1000));
console.log(result1);
const result2 = await new Promise(resolve => setTimeout(() => resolve("操作2完成"), 1000));
console.log(result2);
} catch (error) {
console.log("捕获错误:", error);
}
}
run();
在 async
函数中,你可以使用 await
等待 Promise 的结果,这使得异步代码更简洁易读。
在实际项目中使用
- API 请求
在开发前端应用时,向后端请求数据是最常见的异步操作。通常会使用 Promise
来处理 API 请求, 通常会使用 async/await
来简化这类代码。
js
async function fetchData() {
try {
const response = await fetch('https://api.example.com/data');
const data = await response.json();
console.log("数据:", data);
} catch (error) {
console.error("获取数据失败:", error);
}
}
- 多个异步操作并行执行 (
Promise.all
)
这种方式比一一等待每个请求更加高效,尤其是在多个请求之间没有依赖关系时
例如,加载多个 API 数据:
js
const fetchData1 = fetch('https://api.example.com/data1').then(res => res.json());
const fetchData2 = fetch('https://api.example.com/data2').then(res => res.json());
Promise.all([fetchData1, fetchData2])
.then(([data1, data2]) => {
console.log("数据1:", data1);
console.log("数据2:", data2);
})
.catch(error => {
console.error("加载数据失败:", error);
});
- 串联多个异步操作 (
then
)
一个异步操作完成后再执行下一个操作,这时可以使用 then
链式调用来处理。
例如,先提交表单数据,再获取结果:
js
function submitForm(data) {
return new Promise((resolve, reject) => {
setTimeout(() => {
// 模拟异步表单提交
if (data) resolve("表单提交成功");
else reject("表单提交失败");
}, 1000);
});
}
submitForm({ name: 'John', age: 30 })
.then(result => {
console.log(result); // 输出: 表单提交成功
return fetch('https://api.example.com/result'); // 提交成功后获取结果
})
.then(response => response.json())
.then(data => console.log("结果数据:", data))
.catch(error => console.error("错误:", error));
- 处理复杂的异步控制流 (
async/await
)
async/await
是 Promise
的语法糖,使得异步代码看起来像同步代码,简化了逻辑结构,尤其是处理多层嵌套的异步调用时非常有用。
例如,用户登录后执行后续操作:
js
async function loginUser(credentials) {
try {
const loginResponse = await fetch('https://api.example.com/login', {
method: 'POST',
body: JSON.stringify(credentials),
});
const loginData = await loginResponse.json();
if (loginData.success) {
const userProfile = await fetch('https://api.example.com/user/profile');
const profileData = await userProfile.json();
console.log("用户资料:", profileData);
} else {
console.error("登录失败");
}
} catch (error) {
console.error("发生错误:", error);
}
}
- 错误处理和重试机制
在项目中,经常会遇到某些操作可能会失败的情况,比如网络请求失败。你可以使用 catch
来捕获错误,甚至设置重试机制。
例如,添加重试机制:
js
function fetchWithRetry(url, retries = 3) {
return new Promise((resolve, reject) => {
function attempt() {
fetch(url)
.then(response => {
if (!response.ok) throw new Error("请求失败");
return response.json();
})
.then(resolve)
.catch(error => {
if (retries > 0) {
console.log(`重试剩余次数: ${retries}`);
retries--;
attempt(); // 重试
} else {
reject(error); // 最终失败
}
});
}
attempt();
});
}
fetchWithRetry('https://api.example.com/data')
.then(data => console.log("数据:", data))
.catch(error => console.error("最终错误:", error));
- 动画和延时操作 有时你需要在执行一系列操作时,插入一些动画或延时操作。你可以利用
Promise
来实现这一需求。
例如,延时执行:
js
function delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
delay(1000) // 延迟1秒
.then(() => console.log("1秒后执行"))
.then(() => delay(2000)) // 再延迟2秒
.then(() => console.log("再过2秒执行"));