#金石焕新程
🚀《Promise 全家桶:原理、实现、API、实战,一篇搞定》
Promise 是前端开发中异步编程的基石,但你真的用对了吗?本文从 Promise 的原理讲起,带你实现一个迷你 Promise,再把 Promise 的 10+ 方法一网打尽,最后结合实际开发场景,教你如何优雅地处理异步任务。
一、Promise 是什么?
Promise 是一个表示异步操作最终完成(或失败)及其结果的对象。它有三种状态:
- Pending(进行中)
- Fulfilled(已成功)
- Rejected(已失败)
Promise 的核心在于,它允许你通过 .then()
和 .catch()
方法来处理异步操作的结果。
二、Promise 的原理
Promise 的核心是 事件循环 和 微任务队列。当一个 Promise 被创建时,它会立即执行,并将回调函数放入微任务队列中。一旦 Promise 的状态变为 Fulfilled 或 Rejected,对应的回调函数就会被触发。
javascript
const promise = new Promise((resolve, reject) => {
// 异步操作
setTimeout(() => resolve('Success'), 1000);
});
promise.then(result => console.log(result)); // 'Success'
三、实现一个迷你 Promise
javascript
class MiniPromise {
constructor(executor) {
this.state = 'pending';
this.value = undefined;
this.handlers = [];
const resolve = value => {
if (this.state === 'pending') {
this.state = 'fulfilled';
this.value = value;
this.handlers.forEach(handler => handler());
}
};
const reject = reason => {
if (this.state === 'pending') {
this.state = 'rejected';
this.value = reason;
this.handlers.forEach(handler => handler());
}
};
executor(resolve, reject);
}
then(onFulfilled, onRejected) {
return new MiniPromise((resolve, reject) => {
this.handlers.push(() => {
if (this.state === 'fulfilled') {
onFulfilled(this.value);
} else if (this.state === 'rejected') {
onRejected(this.value);
}
});
});
}
}
四、Promise 的 API
1. Promise.resolve(value)
- 作用:返回一个状态为 Fulfilled 的 Promise。
- 示例:
javascript
Promise.resolve('Hello').then(console.log); // 'Hello'
2. Promise.reject(reason)
- 作用:返回一个状态为 Rejected 的 Promise。
- 示例:
javascript
Promise.reject('Error').catch(console.error); // 'Error'
3. Promise.all(iterable)
- 作用:接收一个 Promise 数组,当所有 Promise 都成功时返回一个包含所有结果的数组。
- 示例:
javascript
Promise.all([fetch('/api/user'), fetch('/api/posts')])
.then(([user, posts]) => console.log(user, posts));
4. Promise.race(iterable)
- 作用:接收一个 Promise 数组,返回第一个完成的 Promise 的结果。
- 示例:
javascript
Promise.race([fetch('/api/user'), fetch('/api/posts')])
.then(result => console.log(result));
5. Promise.allSettled(iterable)
- 作用:接收一个 Promise 数组,返回一个包含所有 Promise 结果的数组(无论成功还是失败)。
- 示例:
javascript
Promise.allSettled([fetch('/api/user'), fetch('/api/posts')])
.then(results => console.log(results));
6. Promise.any(iterable)
- 作用:接收一个 Promise 数组,返回第一个成功的 Promise 的结果。
- 示例:
javascript
Promise.any([fetch('/api/user'), fetch('/api/posts')])
.then(result => console.log(result));
五、Promise 的链式调用
javascript
fetch('/api/user')
.then(response => response.json())
.then(user => console.log(user))
.catch(error => console.error(error));
1. .then(onFulfilled, onRejected)
- 作用:处理 Promise 的成功和失败。
- 示例:
javascript
fetch('/api/user')
.then(response => response.json())
.then(user => console.log(user))
.catch(error => console.error(error));
2. .catch(onRejected)
- 作用:捕获 Promise 的错误。
- 示例:
javascript
fetch('/api/user')
.then(response => response.json())
.catch(error => console.error(error));
3. .finally(onFinally)
- 作用:无论成功还是失败都会执行的回调。
- 示例:
javascript
fetch('/api/user')
.then(response => response.json())
.finally(() => console.log('Done'));
六、Promise 的实际应用
1. 数据加载
javascript
function fetchData(url) {
return fetch(url)
.then(response => response.json())
.catch(error => console.error('Error:', error));
}
fetchData('/api/user').then(user => console.log(user));
2. 异步表单提交
javascript
function submitForm(data) {
return fetch('/api/submit', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data)
}).then(response => response.json());
}
submitForm({ name: 'John', email: 'john@example.com' })
.then(result => console.log(result))
.catch(error => console.error(error));
3. 超时处理
javascript
function timeoutPromise(promise, ms) {
return new Promise((resolve, reject) => {
const timeout = setTimeout(() => reject(new Error('Timeout')), ms);
promise.then(result => {
clearTimeout(timeout);
resolve(result);
}).catch(error => {
clearTimeout(timeout);
reject(error);
});
});
}
timeoutPromise(fetch('/api/user'), 5000)
.then(response => response.json())
.then(user => console.log(user))
.catch(error => console.error(error));
4. 错误处理
javascript
function fetchData(url) {
return fetch(url)
.then(response => {
if (!response.ok) throw new Error('Network response was not ok');
return response.json();
})
.catch(error => console.error('Error:', error));
}
fetchData('/api/user').then(user => console.log(user));
七、总结
Promise 是 JavaScript 异步编程的核心工具,通过 .then()
、.catch()
和 .finally()
方法,可以优雅地处理异步任务。Promise 的链式调用和组合方法(如 Promise.all
、Promise.race
)让复杂的异步流程变得简洁明了。希望本文能帮助你在实际开发中更好地使用 Promise。
🏁 一句话总结
Promise = 异步编程基石 ,.then()
处理结果,.catch()
捕获错误,Promise.all
组合多个 Promise,链式调用让异步流程清晰易读。