Promise 简介
Promise
是一种用于处理异步操作的编程解决方案,通过链式调用有效地解决了回调地狱的问题,使得异步代码结构更加清晰和可读。Promise
有三种状态:进行中 (Pending)
、已成功 (Fulfilled)
和 已失败 (Rejected)
。
- 当异步操作成功时,
Promise
会进入已成功
状态,使用.then()
方法处理成功的结果。 - 当异步操作失败时,
Promise
会进入已失败
状态,使用.catch()
方法处理错误。
常用方法
Promise.all()
:接收一个包含多个Promise
对象的数组,只有当所有Promise
都成功时才会返回成功结果的数组;如果任意一个Promise
失败,它会立即失败,并返回失败的原因。Promise.race()
:同样接收一个Promise
对象的数组,只要其中任意一个Promise
完成(成功或失败),它就会返回该Promise
的结果或错误。.finally()
:无论Promise
的结果是成功还是失败,都会执行的回调函数。
应用场景
-
异步网络请求
使用Promise
来处理异步的网络请求,可以更优雅地处理成功和失败的情况。function fetchData(url) { return new Promise((resolve, reject) => { axios.get(url) .then(response => resolve(response.data)) .catch(error => reject('请求失败: ' + error.message)); }); } fetchData('https://jsonplaceholder.typicode.com/users/1') .then(data => console.log('数据获取成功:', data)) .catch(error => console.error('数据获取失败:', error));
-
替代多层嵌套的回调函数
使用Promise
可以将多层嵌套的回调函数转变为链式调用,简化异步代码的结构。
doSomething(function(result) {
doSomethingElse(result, function(newResult) {
doThirdThing(newResult, function(finalResult) {
console.log('得到最终结果: ' + finalResult);
}, failureCallback);
}, failureCallback);
}, failureCallback);
// 该写成 promise 方案,假设每个函数内都实例化了一个 promise 对象
function doSomething() {
return new Promise((resolve, reject) => {
originalDoSomething(function(result) {
resolve(result);
}, function(err) {
reject(err);
});
});
}
......
// 现在使用 Promise 链调用
doSomething()
.then(doSomethingElse)
.then(doThirdThing)
.then(finalResult => {
console.log('得到最终结果: ' + finalResult);
})
.catch(failureCallback); // 单一的错误处理
- 在处理多个请求时,如果希望在某个请求失败时跳过后续的执行,使用
Promise.allSettled()
const requests = [request1, request2, request3];
const promises = requests.map(request => request());
Promise.allSettled(promises).then(results => {
results.forEach((result, index) => {
if (result.status === 'fulfilled') {
console.log(`请求 ${index + 1} 成功:`, result.value);
} else {
console.log(`请求 ${index + 1} 失败:`, result.reason);
// 跳过后续请求的执行逻辑
}
});
});
-
包装定时器,实现延迟操作
通过Promise
包装setTimeout
,可以简化延迟执行的操作。function delay(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } delay(2000).then(() => { console.log('2秒后执行'); });
Promise.all
示例
-
Promise.all
:处理多个网络请求,当所有请求都成功时才会返回结果。function fetchData(url) { return new Promise((resolve, reject) => { fetch(url) .then(response => { if (!response.ok) { reject('网络响应失败'); } return response.json(); }) .then(data => resolve(data)) .catch(error => reject('请求失败: ' + error.message)); }); } const user1Promise = fetchData('https://jsonplaceholder.typicode.com/users/1'); const user2Promise = fetchData('https://jsonplaceholder.typicode.com/users/2'); Promise.all([user1Promise, user2Promise]) .then(results => { console.log('用户1数据:', results[0]); console.log('用户2数据:', results[1]); }) .catch(error => console.error('请求失败:', error));
封装一个 Promise
类对象
为了更好地理解 Promise
的工作原理,这里封装一个简单的 Promise
类。
class MyPromise {
constructor(executor) {
this.state = 'pending';
this.value = undefined;
executor(this._resolve.bind(this), this._reject.bind(this));
}
_resolve(data) {
this.state = 'fulfilled';
this.value = data;
console.log('完成:', data);
}
_reject(reason) {
this.state = 'rejected';
this.value = reason;
console.log('失败:', reason);
}
then(onFulfilled, onRejected) {
if (this.state === 'fulfilled' && onFulfilled) {
onFulfilled(this.value);
} else if (this.state === 'rejected' && onRejected) {
onRejected(this.value);
}
}
}
const result = new MyPromise((resolve, reject) => {
// resolve(5445);
reject(43434);
});
result.then(
value => console.log('成功:', value),
reason => console.log('失败:', reason)
);
console.log(result);