返回
应许之道——从实现到理解
前端
2024-01-11 11:34:48
在JavaScript中,Promises作为一种强大的工具,帮助我们处理异步任务和提高代码的可读性。然而,理解它们的工作原理并不总是那么容易。本文将带你从实现的角度去探索Promises,深入理解它们的运作方式以及如何有效地使用它们。
Promises的基本原理
Promises是一个封装了异步操作结果的对象,它代表着该操作最终完成或失败的状态。Promises的实现很简单,但非常有效。让我们从头开始一步一步地构建一个Promise的实现。
class Promise {
constructor(executor) {
this.state = "pending";
this.result = undefined;
this.onFulfilledCallbacks = [];
this.onRejectedCallbacks = [];
//立即执行executor函数,可能会同步或异步完成
executor(
(result) => this._resolve(result),
(error) => this._reject(error)
);
}
_resolve(result) {
//检查当前状态,如果已经不是pending,则忽略
if (this.state !== "pending") return;
//将状态更改为fulfilled,并记录结果
this.state = "fulfilled";
this.result = result;
//执行所有onFulfilled回调函数
this.onFulfilledCallbacks.forEach((callback) => callback(result));
}
_reject(error) {
//检查当前状态,如果已经不是pending,则忽略
if (this.state !== "pending") return;
//将状态更改为rejected,并记录错误信息
this.state = "rejected";
this.result = error;
//执行所有onRejected回调函数
this.onRejectedCallbacks.forEach((callback) => callback(error));
}
then(onFulfilled, onRejected) {
//如果onFulfilled或onRejected不是函数,则忽略
if (typeof onFulfilled !== "function") onFulfilled = (result) => result;
if (typeof onRejected !== "function") onRejected = (error) => { throw error; };
//创建新的Promise对象
const newPromise = new Promise(() => {});
//将当前Promise的成功回调添加到新Promise的等待列表中
this.onFulfilledCallbacks.push((result) => {
//在新的Promise中异步执行onFulfilled,并传递result
setTimeout(() => {
try {
const x = onFulfilled(result);
_resolvePromise(newPromise, x);
} catch (error) {
_rejectPromise(newPromise, error);
}
}, 0);
});
//将当前Promise的失败回调添加到新Promise的等待列表中
this.onRejectedCallbacks.push((error) => {
//在新的Promise中异步执行onRejected,并传递error
setTimeout(() => {
try {
const x = onRejected(error);
_resolvePromise(newPromise, x);
} catch (error) {
_rejectPromise(newPromise, error);
}
}, 0);
});
//返回新的Promise对象
return newPromise;
}
catch(onRejected) {
return this.then(undefined, onRejected);
}
finally(onFinally) {
//无论Promise是成功还是失败,都执行onFinally
return this.then(
(result) => {
setTimeout(() => {
onFinally();
}, 0);
return result;
},
(error) => {
setTimeout(() => {
onFinally();
}, 0);
throw error;
}
);
}
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) => {
let results = [];
let pendingPromises = promises.length;
promises.forEach((promise, index) => {
promise
.then(
(result) => {
results[index] = result;
pendingPromises--;
if (pendingPromises === 0) resolve(results);
},
(error) => reject(error)
);
});
});
}
static race(promises) {
return new Promise((resolve, reject) => {
promises.forEach((promise) => {
promise
.then((result) => resolve(result))
.catch((error) => reject(error));
});
});
}
}
function _resolvePromise(promise, x) {
if (promise === x) {
throw new TypeError("Cannot resolve a promise with itself.");
}
if (x instanceof Promise) {
x.then(
(result) => _resolvePromise(promise, result),
(error) => _rejectPromise(promise, error)
);
} else if (x && (typeof x === "object" || typeof x === "function")) {
let then;
try {
then = x.then;
} catch (error) {
_rejectPromise(promise, error);
return;
}
if (typeof then === "function") {
let called = false;
try {
then.call(
x,
(result) => {
if (called) return;
called = true;
_resolvePromise(promise, result);
},
(error) => {
if (called) return;
called = true;
_rejectPromise(promise, error);
}
);
} catch (error) {
if (called) return;
_rejectPromise(promise, error);
}
} else {
_resolvePromise(promise, x);
}
} else {
_resolvePromise(promise, x);
}
}
function _rejectPromise(promise, error) {
promise.state = "rejected";
promise.result = error;
promise.onRejectedCallbacks.forEach((callback) => callback(error));
}
Promises的应用
Promises在JavaScript中有着广泛的应用,以下是一些常见的场景:
- 处理异步操作。Promises可以帮助我们轻松地处理异步操作,比如网络请求、文件读写等。
- 处理错误。Promises可以帮助我们捕获和处理错误,使我们的代码更加健壮。
- 实现链式调用。Promises支持链式调用,这使得我们的代码更加简洁和易读。
- 实现并发操作。Promises可以帮助我们实现并发操作,比如同时发送多个网络请求。
结论
Promises在JavaScript中发挥着重要作用,理解它们的原理和应用对于任何想深入探索现代JavaScript应用程序的开发者来说都是必不可少的。本文带你从头开始了解Promises,从它们的实现到应用,希望能够帮助你更好地理解和使用它们。