手写 Promise 进阶版:深入理解异步编程的利器
2024-02-10 21:44:15
手写 Promise:掌握异步编程的利器
什么是 Promise?
Promise 是一种 JavaScript 对象,它代表着异步操作的最终结果,无论是成功还是失败。它允许我们编写可读且可维护的代码,轻松应对异步操作带来的复杂性。
手写 Promise 的步骤
1. 初始化 Promise
const promise = new Promise((resolve, reject) => {
// 异步操作在这里执行
});
2. 异步调用
promise.then(result => {
// 成功后执行的代码
}).catch(error => {
// 失败后执行的代码
});
3. 链式调用
promise
.then(result => {
return '新的 Promise 结果';
})
.then(newResult => {
// 处理新的 Promise 结果
})
.catch(error => {
// 处理错误
});
4. API
4.1 .resolve
Promise.resolve(value).then(value => {
// 成功后执行的代码
});
4.2 .reject
Promise.reject(error).then(error => {
// 失败后执行的代码
});
4.3 .all
Promise.all([promise1, promise2]).then([result1, result2] => {
// 所有 Promise 成功后执行的代码
});
4.4 .race
Promise.race([promise1, promise2]).then(result => {
// 第一个 Promise 成功或失败后执行的代码
});
实现 Promise API 的手写 Promise
让我们深入了解一下如何手动实现 Promise 的 API。以下是一个用 JavaScript 编写的简单实现:
class Promise {
constructor(executor) {
this.state = 'pending';
this.value = undefined;
this.error = undefined;
this.thenCallbacks = [];
this.catchCallbacks = [];
try {
executor(this.resolve.bind(this), this.reject.bind(this));
} catch (error) {
this.reject(error);
}
}
resolve(value) {
if (this.state !== 'pending') return;
this.state = 'fulfilled';
this.value = value;
for (const callback of this.thenCallbacks) {
callback(value);
}
}
reject(error) {
if (this.state !== 'pending') return;
this.state = 'rejected';
this.error = error;
for (const callback of this.catchCallbacks) {
callback(error);
}
}
then(onFulfilled, onRejected) {
return new Promise((resolve, reject) => {
this.thenCallbacks.push(result => {
try {
const nextValue = onFulfilled ? onFulfilled(result) : result;
resolve(nextValue);
} catch (error) {
reject(error);
}
});
if (onRejected) {
this.catchCallbacks.push(error => {
try {
const nextValue = onRejected(error);
resolve(nextValue);
} catch (error) {
reject(error);
}
});
}
});
}
catch(onRejected) {
return this.then(undefined, onRejected);
}
static resolve(value) {
return new Promise(resolve => {
resolve(value);
});
}
static reject(error) {
return new Promise((resolve, reject) => {
reject(error);
});
}
static all(promises) {
return new Promise((resolve, reject) => {
const results = [];
let count = 0;
promises.forEach((promise, index) => {
promise
.then(result => {
results[index] = result;
count++;
if (count === promises.length) {
resolve(results);
}
})
.catch(error => {
reject(error);
});
});
});
}
static race(promises) {
return new Promise((resolve, reject) => {
promises.forEach(promise => {
promise
.then(result => {
resolve(result);
})
.catch(error => {
reject(error);
});
});
});
}
}
代码示例
以下是一个使用手写 Promise 的示例:
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('异步操作的结果');
}, 1000);
});
promise.then(result => {
console.log(result); // '异步操作的结果'
});
常见问题解答
1. 为什么使用 Promise?
Promise 提供了一种清晰、可读的方式来处理异步操作,使代码更易于维护和调试。
2. .then 和 .catch 方法有什么区别?
.then 方法用于处理 Promise 成功时的结果,而 .catch 方法用于处理 Promise 失败时的错误。
3. Promise 可以嵌套吗?
是的,Promise 可以链式调用,允许我们将多个异步操作串联在一起。
4. Promise.all 和 Promise.race 方法有什么区别?
Promise.all 等待所有给定的 Promise 都解决完毕,然后返回一个包含所有结果的数组。Promise.race 则等待第一个给定的 Promise 解决完毕,然后返回该结果。
5. 如何处理拒绝的 Promise?
使用 .catch 方法来处理拒绝的 Promise 并捕获错误。
结论
手写 Promise 是一种强大的技术,可以让你充分利用异步编程的优势。通过理解其原理和实现,你可以编写更健壮、更可读的代码。