实现 Promise/A+规范

实现 Promise/A+ 规范

阅文前置

首先了解清楚 Promise/A+ 规范组成部分

  1. Promise 的三种状态:pending、fulfilled 和 rejected
  2. 状态只能从 pending 转到 fulfilled 或者 rejected,并且状态一旦改变就不会再变
  3. Promise 实现需要遵守 thenable 接口规范, then 方法用来注册回调函数, then 必须返回一个新的 Promise 实例
  4. then 方法支持链式调用,当前 Promise 达成或拒绝后,会调用后面 then 中的回调函数
  5. catch 方法用于指定 Promise reject 时的回调函数
  6. finally 方法用于指定无论结果如何都会执行的回调函数。
  7. Promise 需要有一个 resolve 和 reject 静态方法用来改变 Promise 的状态
  8. Promise 静态 all、race、allSettled、any 方法

如何实现以上所述

  1. 定义一个类名称为 GPromise 将实现 Promise/A+ 规范
  2. 实现 GPromise 构造函数
  3. 实现 resolve 和 reject 方法
  4. 实现 then 、catch 、finally 方法
  5. 实现 all、race、allSettled、any 方法

实现步骤

1. 实现 GPromise 构造函数和基本状态

  1. Promise 一开始状态都是 pending,只有通过调用 resolve 或 reject 才能将状态改变为 fulfilled 或 rejected 且状态不可逆
  2. resolve 和 reject 用于传递异步操作的结果在异步操作成功时,调用 resolve 并传递结果值;在异步操作失败时,调用 reject 并传递失败原因
  3. resolve 和 reject 可以触发 then/catch 后续操作一旦 Promise 状态改变,会触发然后链上的回调函数执行
  4. resolve 和 reject 隔离异步操作结果通过它们,可以在异步操作完成后再进行结果处理,异步操作结果的值和状态的改变都被包装在 Promise 内部
  5. 保证 executor 函数的标准格式 Promise 接受一个 executor 执行器函数,规范中 executor 需要传入 resolve 和 reject 两个函数参数以处理异步结果

代码

js 复制代码
/**
 * Promise 状态枚举
 */
const PENDING = 'pending';
const FULFILLED = 'fulFilled';
const REJECTED = 'rejected';

class GPromise {
    constructor(executor) {
        // 初始化状态为 pending
        this.status = PENDING;
        // 初始化成功的值为 undefined
        this.value = undefined;
        // 初始化失败的值为 undefined
        this.reason = undefined;
        // 初始化成功处理函数队列
        this.onFulfilledCBS = [];
        // 初始化失败处理函数队列
        this.onRejectedCBS = [];

        // 定义resolve方法
        const resolve = (value) => {
            // 只有在pending状态才能更改状态和值
            if (this.status === PENDING) {
                this.status = FULFILLED;
                this.value = value;
                // 执行所有成功处理函数
                this.onFulfilledCBS.forEach((callback) => callback());
            }
        };

        // 定义reject方法
        const reject = (reason) => {
            // 只有在pending状态才能更改状态和原因
            if (this.status === PENDING) {
                this.status = REJECTED;
                this.reason = reason;
                // 执行所有失败处理函数
                this.onRejectedCBS.forEach((callback) => callback());
            }
        };

        // 立即执行 executor,处理异常
        try {
            executor(resolve, reject);
        } catch (error) {
            // 如果执行器函数抛出异常,将Promise状态更改为rejected
            reject(error);
        }
    }
}

解释 executor 立即执行函数

  1. executor 函数的作用是启动 Promise 并传递异步操作的结果
  2. 当异步操作成功时,调用 resolve,将结果值传递出去,Promise 的状态会变为 fulfilled
  3. 当异步操作失败时,调用 reject,将错误原因传递出去,Promise 的状态会变为 rejected
  4. executor 会在 Promise 实例创建时立即执行,异步操作的启动会放在 executor 中
  5. 然后 Promise 通过then/catch等方法指定回调,在异步操作完成后,根据结果调用对应回调函数
  6. 所以 executor 是 Promise 的一个关键,它内部运行的异步任务会影响 Promise 的状态变化
  7. 通过它,Promise 可以知道异步操作什么时候结束,并采取相应的后续操作

2. 实现 then 方法

  • 注册回调then 接收两个参数,onFulfilled 和 onRejected,分别代表 Promise 成功或失败的回调。
js 复制代码
promise.then(onFulfilled, onRejected);
  • 返回新的 Promise then 方法会返回一个新的 Promise 实例,这样就可以实现 Promise 的链式调用。
js 复制代码
promise.then().then().then(); 
  • 回调执行 Promise 如果成功了,会执行 onFulfilled,把值传给它;如果失败了,会执行 onRejected,把原因传给它
  • 传递值 then 方法会将上一个 Promise 的结果作为参数,传递给下一个 then 的回调函数
  • 处理错误在 then 的回调函数中,如果抛出异常,那么 then 返回的 Promise 状态为 rejected
  • 异步执行 then 方法总是会返回一个新的 Promise,即使回调是同步的,then 的调用也会延迟到当前调用栈清空后再执行

先封装一个工具方法 resolvePromise

用来处理 then 方法链式调用处理 resolve 或者 reject

js 复制代码
/**
 * 解析 Promise 链式调用中的结果值x,并决定是执行resolve还是reject
 *
 * @param {Promise} promise2 - 下一个新的Promise对象
 * @param {any} x - 当前Promise回调return的值
 * @param {Function} resolve - 执行下一个Promise的resolve方法
 * @param {Function} reject - 执行下一个Promise的reject方法
 */
function resolvePromise(promise2, x, resolve, reject) {
    // 如果值 x 和 promise2 是同一个引用,以 TypeError 为据因拒绝 promise2
    // 这是为了防止死循环
    if (promise2 === x) {
        return reject(new TypeError('Chaining cycle detected for promise'));
    }

    // 标记是否已调用,防止多次调用
    let called = false;

    // 2. 如果 x 是 GPromise 实例
    if (x instanceof GPromise) {
        // 根据 x 的状态调用 resolve 或 reject
        x.then(
            (y) => {
                resolvePromise(promise2, y, resolve, reject);
            },
            (reason) => {
                reject(reason);
            }
        );
    } else if (x !== null && (typeof x === 'object' || typeof x === 'function')) {
        // 3. 如果 x 是对象或函数
        try {
            // 获取 x 的 then 方法
            const then = x.then;
            if (typeof then === 'function') {
                // 如果 then 是函数
                // 使用 x 作为上下文调用 then 方法
                then.call(
                    x,
                    (y) => {
                        // 成功回调
                        if (called) return; // 如果已经调用过,直接返回
                        called = true;
                        // 递归处理 y
                        resolvePromise(promise2, y, resolve, reject);
                    },
                    (reason) => {
                        // 失败回调
                        if (called) return; // 如果已经调用过,直接返回
                        called = true;
                        reject(reason);
                    }
                );
            } else {
                // 如果 then 不是函数
                // 直接调用 resolve
                resolve(x);
            }
        } catch (error) {
            // 如果获取或调用 then 方法抛出异常
            if (called) return; // 如果已经调用过,直接返回
            called = true;
            reject(error);
        }
    } else {
        // 4. 如果 x 不是对象或函数直接调用 resolve
        resolve(x);
    }
}

对 then 方法实现代码

js 复制代码
then(onFulfilled, onRejected) {
    // 处理默认回调函数
    onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : (value) => value;
    onRejected =
        typeof onRejected === 'function'
            ? onRejected
            : (reason) => {
                  throw reason;
              };

    // 创建新的Promise
    const promise2 = new GPromise((resolve, reject) => {
        // 根据状态区分处理
        if (this.status === FULFILLED) {
            // 使用setTimeout保证异步调用
            setTimeout(() => {
                try {
                    // 调用onFulfilled,并获取返回值
                    const x = onFulfilled(this.value);
                    // 使用返回值x和新的Promise实例promise2来处理resolve和reject
                    resolvePromise(promise2, x, resolve, reject);
                } catch (error) {
                    // 如果处理函数抛出异常,则将promise2状态更改为rejected
                    reject(error);
                }
            }, 0);
        } else if (this.status === REJECTED) {
            // 使用setTimeout保证异步调用
            setTimeout(() => {
                try {
                    // 调用onRejected,并获取返回值
                    const x = onRejected(this.reason);
                    // 使用返回值x和新的Promise实例promise2来处理resolve和reject
                    resolvePromise(promise2, x, resolve, reject);
                } catch (error) {
                    // 如果处理函数抛出异常,则将promise2状态更改为rejected
                    reject(error);
                }
            }, 0);
        } else if (this.status === PENDING) {
            // 如果当前Promise状态仍为pending,将处理函数加入相应的队列中
            this.onFulfilledCBS.push(() => {
                // 使用setTimeout保证异步调用
                setTimeout(() => {
                    try {
                        // 调用onFulfilled,并获取返回值
                        const x = onFulfilled(this.value);
                        // 使用返回值x和新的Promise实例promise2来处理resolve和reject
                        resolvePromise(promise2, x, resolve, reject);
                    } catch (error) {
                        // 如果处理函数抛出异常,则将promise2状态更改为rejected
                        reject(error);
                    }
                }, 0);
            });

            this.onRejectedCBS.push(() => {
                // 使用setTimeout保证异步调用
                setTimeout(() => {
                    try {
                        // 调用onRejected,并获取返回值
                        const x = onRejected(this.reason);
                        // 使用返回值x和新的Promise实例promise2来处理resolve和reject
                        resolvePromise(promise2, x, resolve, reject);
                    } catch (error) {
                        // 如果处理函数抛出异常,则将promise2状态更改为rejected
                        reject(error);
                    }
                }, 0);
            });
        }
    });
    // 返回 promise2 以支持链式调用
    return promise2;
}

实现 catch 方法

js 复制代码
catch(onRejected) {
    // 调用then方法,仅传入失败处理函数
    return this.then(null, onRejected);
}

实现 finally 方法

js 复制代码
/**
 * 主要思路就是:
 * 1. 保存 this 引用到 self
 * 2. 根据当前状态立即执行或者推入回调队列
 * 3. 在回调中先执行 callback,再执行 resolve/reject
 * 4. 最后返回 self 而不是新的 Promise
 * 5. 这样可以避免创建新的 Promise,直接在原 Promise 对象上操作。
 */
finally(callback) {
    let self = this;
    return new GPromise((resolve, reject) => {
        const onFinally = () => {
            queueMicrotask(() => {
                try {
                    callback();
                } catch (error) {
                    reject(error);
                }
            });
        };

        const onFulfilled = (value) => {
            onFinally();
            resolve(value);
        };

        const onRejected = (reason) => {
            onFinally();
            reject(reason);
        };

        switch (self.status) {
            case FULFILLED:
                onFulfilled(self.value);
                break;
            case REJECTED:
                onRejected(self.reason);
                break;
            case PENDING:
                self.onFulfilledCBS.push(onFulfilled);
                self.onRejectedCBS.push(onRejected);
                break;
        }
    });
}

静态方法 resolve

js 复制代码
static resolve(value) {
    if (value instanceof GPromise) {
        return value;
    }
    return new GPromise((resolve, reject) => {
        resolve(value);
    });
}
  1. 如果传入的值已经是一个 Promise 实例,那么直接返回这个实例。
  2. 否则,返回一个新的 Promise 实例,并在 executor 中立即调用 resolve 将传入的值作为成功结果。
  3. 之所以需要作这个判断和处理,是因为 Promise.resolve 可以接受不同类型的参数:
    • 如果是一个 Promise 实例,直接返回即可,不需要做处理
    • 如果是一个 thenable 对象,需要转换为一个 Promise 对象
    • 如果是原始类型的值,需要用一个 resolved Promise 包装起来
  4. 这样,Promise.resolve 可以把不同的值统一转换为 Promise 对象,使其更易于处理

静态方法 reject

js 复制代码
static reject(reason) {
    return new GPromise((resolve, reject) => {
        reject(reason);
    });
}

静态方法 all

多个 Promise 包装成一个新的 Promise,只有当所有的 Promise 都 resolve 时,新的 Promise 才会 resolve,一旦有任意一个 Promise reject,新的 Promise 就会 reject

js 复制代码
static all(promises) {
    return new GPromise((resolve, reject) => {
        const result = [];
        let resolvedCount = 0;

        promises.forEach((promise, index) => {
            GPromise.resolve(promise).then(
                (value) => {
                    result[index] = value;
                    resolvedCount++;
                    if (resolvedCount === promises.length) {
                        resolve(result);
                    }
                },
                (reason) => {
                    reject(reason);
                }
            );
        });
    });
}

这里的关键逻辑:

  1. 使用递归 Promise.resolve 处理非 Promise 值
  2. 保存每个 promise 结果到结果数组
  3. 计数追踪成功的 promise 数量
  4. 当全部成功则 resolve,任何一个失败则 reject

静态方法 race

将多个 Promise 包装成一个新的 Promise,新的 Promise 一旦有一个 Promise resolve或者reject的话,新的Promise就会采取对应状态

js 复制代码
static race(promises) {
    return new GPromise((resolve, reject) => {
        promises.forEach((promise) => {
            GPromise.resolve(promise).then(
                (value) => {
                    resolve(value);
                },
                (reason) => {
                    reject(reason);
                }
            );
        });
    });
}

静态方法 allSettled

将多个 Promise 包装成一个新的 Promise,只有等到所有这些参数实例都返回结果,不管是 resolved 还是 rejected,新的 Promise 才会结束

js 复制代码
static allSettled(promises) {
    return new GPromise((resolve, reject) => {
        const result = [];
        let settledCount = 0;
        promises.forEach((promise, index) => {
            GPromise.resolve(promise).then(
                (value) => {
                    result[index] = { status: FULFILLED, value };
                    settledCount++;
                    if (settledCount === promises.length) {
                        resolve(result);
                    }
                },
                (reason) => {
                    result[index] = { status: REJECTED, reason };
                    settledCount++;
                    if (settledCount === promises.length) {
                        resolve(result);
                    }
                }
            );
        });
    });
}

静态方法 any

将多个 Promise 包装成一个新的 Promise,只要其中的一个 Promise resolve,新的 Promise 就会 resolve,全部失败则会返回错误原因

js 复制代码
static any(promises) {
    return new GPromise((resolve, reject) => {
        const errors = [];
        let rejectedCount = 0;

        promises.forEach((promise, index) => {
            GPromise.resolve(promise).then(
                (value) => {
                    resolve(value);
                },
                (reason) => {
                    errors[index] = reason;
                    rejectedCount++;
                    if (rejectedCount === promises.length) {
                        reject(new AggregateError(errors, 'All promises were rejected'));
                    }
                }
            );
        });
    });
}

使用 Promise/A+ 测试包跑一下

  1. 安装 Promise/A+ 测试库

    npm install promises-aplus-tests -D

  2. 在项目中创建测试文件 test.js,引入测试库

js 复制代码
const test = require('promises-aplus-tests');
const adapter = require('./utils/adapter');

test(adapter, function (err) {
    if (err) {
        console.error('Promises/A+ 测试失败:');
        console.error(err);
    } else {
        console.log('Promises/A+ 测试通过');
    }
});
  1. 创建测试适配器适配器是一个类,需要实现以下方法:

    • deferred() - 返回 {promise, resolve, reject} 对象
    • resolved(value) - 返回resolved的Promise
    • rejected(reason) - 返回rejected的Promise
  2. 适配器 adapter.js :

js 复制代码
const { GPromise } = require('../js/GPromise'); // 导入我们实现的 GPromise 模块

// 暴露适配器对象
module.exports = {
    resolved: GPromise.resolve,
    rejected: GPromise.reject,
    deferred() {
        const result = {};
        result.promise = new GPromise((resolve, reject) => {
            result.resolve = resolve;
            result.reject = reject;
        });
        return result;
    }
};
  1. 终端执行脚本

    node test.js

测试 GPromise 结果

完整代码结构

js 复制代码
/**
 * Promise状态枚举
 */
const PENDING = 'pending';
const FULFILLED = 'fulFilled';
const REJECTED = 'rejected';

class GPromise {
    constructor(executor) {
        // 初始化状态为pending
        this.status = PENDING;
        // 初始化成功的值为undefined
        this.value = undefined;
        // 初始化失败的原因为undefined
        this.reason = undefined;
        // 初始化成功处理函数队列
        this.onFulfilledCBS = [];
        // 初始化失败处理函数队列
        this.onRejectedCBS = [];

        // 定义resolve方法
        const resolve = (value) => {
            // 只有在pending状态才能更改状态和值
            if (this.status === PENDING) {
                this.status = FULFILLED;
                this.value = value;
                // 执行所有成功处理函数
                this.onFulfilledCBS.forEach((callback) => callback());
            }
        };

        // 定义reject方法
        const reject = (reason) => {
            // 只有在pending状态才能更改状态和原因
            if (this.status === PENDING) {
                this.status = REJECTED;
                this.reason = reason;
                // 执行所有失败处理函数
                this.onRejectedCBS.forEach((callback) => callback());
            }
        };

        // 立即执行 executor,处理异常
        try {
            executor(resolve, reject);
        } catch (error) {
            // 如果执行器函数抛出异常,将Promise状态更改为rejected
            reject(error);
        }
    }
    /**
     * then 方法,参数分别为成功和失败的回调
     *
     * @param {Function} onFulfilled - 成功回调
     * @param {Function} onRejected - 失败回调
     * @return {Promise} 返回一个新的 Promise 对象
     */
    then(onFulfilled, onRejected) {
        // 处理默认回调函数
        onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : (value) => value;
        onRejected =
            typeof onRejected === 'function'
                ? onRejected
                : (reason) => {
                      throw reason;
                  };

        // 创建新的Promise
        const promise2 = new GPromise((resolve, reject) => {
            // 根据状态区分处理
            if (this.status === FULFILLED) {
                // 使用setTimeout保证异步调用
                setTimeout(() => {
                    try {
                        // 调用onFulfilled,并获取返回值
                        const x = onFulfilled(this.value);
                        // 使用返回值x和新的Promise实例promise2来处理resolve和reject
                        resolvePromise(promise2, x, resolve, reject);
                    } catch (error) {
                        // 如果处理函数抛出异常,则将promise2状态更改为rejected
                        reject(error);
                    }
                }, 0);
            } else if (this.status === REJECTED) {
                // 使用setTimeout保证异步调用
                setTimeout(() => {
                    try {
                        // 调用onRejected,并获取返回值
                        const x = onRejected(this.reason);
                        // 使用返回值x和新的Promise实例promise2来处理resolve和reject
                        resolvePromise(promise2, x, resolve, reject);
                    } catch (error) {
                        // 如果处理函数抛出异常,则将promise2状态更改为rejected
                        reject(error);
                    }
                }, 0);
            } else if (this.status === PENDING) {
                // 如果当前Promise状态仍为pending,将处理函数加入相应的队列中
                this.onFulfilledCBS.push(() => {
                    // 使用setTimeout保证异步调用
                    setTimeout(() => {
                        try {
                            // 调用onFulfilled,并获取返回值
                            const x = onFulfilled(this.value);
                            // 使用返回值x和新的Promise实例promise2来处理resolve和reject
                            resolvePromise(promise2, x, resolve, reject);
                        } catch (error) {
                            // 如果处理函数抛出异常,则将promise2状态更改为rejected
                            reject(error);
                        }
                    }, 0);
                });

                this.onRejectedCBS.push(() => {
                    // 使用setTimeout保证异步调用
                    setTimeout(() => {
                        try {
                            // 调用onRejected,并获取返回值
                            const x = onRejected(this.reason);
                            // 使用返回值x和新的Promise实例promise2来处理resolve和reject
                            resolvePromise(promise2, x, resolve, reject);
                        } catch (error) {
                            // 如果处理函数抛出异常,则将promise2状态更改为rejected
                            reject(error);
                        }
                    }, 0);
                });
            }
        });
        // 返回 promise2 以支持链式调用
        return promise2;
    }

    catch(onRejected) {
        // 调用then方法,仅传入失败处理函数
        return this.then(null, onRejected);
    }
    /**
     * 主要思路就是:
     * 1. 保存 this 引用到 self
     * 2. 根据当前状态立即执行或者推入回调队列
     * 3. 在回调中先执行 callback,再执行 resolve/reject
     * 4. 最后返回 self 而不是新的 Promise
     * 5. 这样可以避免创建新的 Promise,直接在原 Promise 对象上操作。
     */
    finally(callback) {
        let self = this;
        return new GPromise((resolve, reject) => {
            const onFinally = () => {
                queueMicrotask(() => {
                    try {
                        callback();
                    } catch (error) {
                        reject(error);
                    }
                });
            };

            const onFulfilled = (value) => {
                onFinally();
                resolve(value);
            };

            const onRejected = (reason) => {
                onFinally();
                reject(reason);
            };

            switch (self.status) {
                case FULFILLED:
                    onFulfilled(self.value);
                    break;
                case REJECTED:
                    onRejected(self.reason);
                    break;
                case PENDING:
                    self.onFulfilledCBS.push(onFulfilled);
                    self.onRejectedCBS.push(onRejected);
                    break;
            }
        });
    }

    static resolve(value) {
        if (value instanceof GPromise) {
            return value;
        }
        return new GPromise((resolve, reject) => {
            resolve(value);
        });
    }

    static reject(reason) {
        return new GPromise((resolve, reject) => {
            reject(reason);
        });
    }
    static all(promises) {
        return new GPromise((resolve, reject) => {
            const result = [];
            let resolvedCount = 0;

            // 遍历 promises 获取每个 promise 的结果
            promises.forEach((promise, index) => {
                // 处理非 Promise 值
                GPromise.resolve(promise).then(
                    // promise 成功的回调
                    (value) => {
                        // 在对应下标位置保存结果
                        result[index] = value;
                        resolvedCount++;
                        // 如果全部成功
                        if (resolvedCount === promises.length) {
                            // resolve 新 promise
                            resolve(result);
                        }
                    },
                    (reason) => {
                        reject(reason);
                    }
                );
            });
        });
    }

    static race(promises) {
        return new GPromise((resolve, reject) => {
            promises.forEach((promise) => {
                GPromise.resolve(promise).then(
                    (value) => {
                        resolve(value);
                    },
                    (reason) => {
                        reject(reason);
                    }
                );
            });
        });
    }
    static allSettled(promises) {
        return new GPromise((resolve, reject) => {
            const result = [];
            let settledCount = 0;
            promises.forEach((promise, index) => {
                GPromise.resolve(promise).then(
                    (value) => {
                        result[index] = { status: FULFILLED, value };
                        settledCount++;
                        if (settledCount === promises.length) {
                            resolve(result);
                        }
                    },
                    (reason) => {
                        result[index] = { status: REJECTED, reason };
                        settledCount++;
                        if (settledCount === promises.length) {
                            resolve(result);
                        }
                    }
                );
            });
        });
    }

    static any(promises) {
        return new GPromise((resolve, reject) => {
            const errors = [];
            let rejectedCount = 0;

            promises.forEach((promise, index) => {
                GPromise.resolve(promise).then(
                    (value) => {
                        resolve(value);
                    },
                    (reason) => {
                        errors[index] = reason;
                        rejectedCount++;
                        if (rejectedCount === promises.length) {
                            reject(new AggregateError(errors, 'All promises were rejected'));
                        }
                    }
                );
            });
        });
    }
}

/**
 * 解析 Promise 链式调用中的结果值x,并决定是执行resolve还是reject
 *
 * @param {Promise} promise2 - 下一个新的Promise对象
 * @param {any} x - 当前Promise回调return的值
 * @param {Function} resolve - 执行下一个Promise的resolve方法
 * @param {Function} reject - 执行下一个Promise的reject方法
 */
function resolvePromise(promise2, x, resolve, reject) {
    // 如果值 x 和 promise2 是同一个引用,以 TypeError 为据因拒绝 promise2
    // 这是为了防止死循环
    if (promise2 === x) {
        return reject(new TypeError('Chaining cycle detected for promise'));
    }

    // 标记是否已调用,防止多次调用
    let called = false;

    // 2. 如果 x 是 GPromise 实例
    if (x instanceof GPromise) {
        // 根据 x 的状态调用 resolve 或 reject
        x.then(
            (y) => {
                resolvePromise(promise2, y, resolve, reject);
            },
            (reason) => {
                reject(reason);
            }
        );
    } else if (x !== null && (typeof x === 'object' || typeof x === 'function')) {
        // 3. 如果 x 是对象或函数
        try {
            // 获取 x 的 then 方法
            const then = x.then;
            if (typeof then === 'function') {
                // 如果 then 是函数
                // 使用 x 作为上下文调用 then 方法
                then.call(
                    x,
                    (y) => {
                        // 成功回调
                        if (called) return; // 如果已经调用过,直接返回
                        called = true;
                        // 递归处理 y
                        resolvePromise(promise2, y, resolve, reject);
                    },
                    (reason) => {
                        // 失败回调
                        if (called) return; // 如果已经调用过,直接返回
                        called = true;
                        reject(reason);
                    }
                );
            } else {
                // 如果 then 不是函数
                // 直接调用 resolve
                resolve(x);
            }
        } catch (error) {
            // 如果获取或调用 then 方法抛出异常
            if (called) return; // 如果已经调用过,直接返回
            called = true;
            reject(error);
        }
    } else {
        // 4. 如果 x 不是对象或函数直接调用 resolve
        resolve(x);
    }
}

module.exports = {
    GPromise
};

·······························································································································

相关推荐
司篂篂1 小时前
axios二次封装
前端·javascript·vue.js
姚*鸿的博客1 小时前
pinia在vue3中的使用
前端·javascript·vue.js
Jiaberrr3 小时前
JS实现树形结构数据中特定节点及其子节点显示属性设置的技巧(可用于树形节点过滤筛选)
前端·javascript·tree·树形·过滤筛选
我码玄黄3 小时前
THREE.js:网页上的3D世界构建者
开发语言·javascript·3d
爱喝水的小鼠4 小时前
Vue3(一) Vite创建Vue3工程,选项式API与组合式API;setup的使用;Vue中的响应式ref,reactive
前端·javascript·vue.js
小晗同学4 小时前
Vue 实现高级穿梭框 Transfer 封装
javascript·vue.js·elementui
WeiShuai4 小时前
vue-cli3使用DllPlugin优化webpack打包性能
前端·javascript
forwardMyLife4 小时前
element-plus的面包屑组件el-breadcrumb
javascript·vue.js·ecmascript
mez_Blog6 小时前
个人小结(2.0)
前端·javascript·vue.js·学习·typescript
珊珊而川6 小时前
【浏览器面试真题】sessionStorage和localStorage
前端·javascript·面试