IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 开发测试 -> 用TS实现Promise(官方测试工具测试通过) -> 正文阅读

[开发测试]用TS实现Promise(官方测试工具测试通过)

Promises/A+ 规范文档

代码实现

enum States {
    PENDING = "pending",
    FULFILLED = "fulfilled",
    REJECTED = "rejected",
}

interface Resolve<T> {
    (value: T | PromiseLike<T>): void;
}

interface Reject {
    (reason?: any): void;
}

interface Executor<T> {
    (resolve: Resolve<T>, reject: Reject): void;
}

//  PromisesA+ 1.1
interface PromiseLike<T> {
    then<TResult1 = T, TResult2 = never>(
        //  PromisesA+ 2.2.1
        onFulfilled?: ((value: T | PromiseLike<T>) => TResult1 | PromiseLike<TResult1>) | undefined | null,
        onRejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null
    ): PromiseLike<TResult1 | TResult2>;
}

export class MyPromise<T> {
    private state: States = States.PENDING;
    private onFulfilledCallbacks = [] as (() => void)[]; //  成功时的回调函数
    private onRejectedCallbacks = [] as (() => void)[]; //  失败时的回调函数
    private value!: T | PromiseLike<T>;
    private reason: any;

    constructor(executor: Executor<T>) {
        try {
            executor(this.resolve, this.reject);
        } catch (e) {
            // PromisesA + 1.4
            this.reject(e);
        }
    }

    //  PromisesA+ 1.3 | PromisesA+ 2.1
    private resolve: Resolve<T> = (value: T | PromiseLike<T>) => {
        try {
            //  PromisesA+ 2.2.4 异步调用,用setTimeout模拟创建微任务
            setTimeout(() => {
                if (this.state === States.PENDING) {
                    this.state = States.FULFILLED;
                    this.value = value;
                    //  PromisesA+ 2.2.6.1
                    this.onFulfilledCallbacks.forEach((fn) => fn());
                    this.onFulfilledCallbacks = [];
                }
            });
        } catch (e) {
            this.reject(e);
        }
    };

    // PromisesA+ 1.5
    private reject: Reject = (reason: any) => {
        try {
            //  PromisesA+ 2.2.4 异步调用,用setTimeout模拟创建微任务
            setTimeout(() => {
                if (this.state === States.PENDING) {
                    this.state = States.REJECTED;
                    this.reason = reason;
                    //  PromisesA+ 2.2.6.2
                    this.onRejectedCallbacks.forEach((fn) => fn());
                    this.onRejectedCallbacks = [];
                }
            });
        } catch (e) {
            this.reject(e);
        }
    };

    //  PromisesA+ 1.2 | PromisesA+ 2.2
    then<TResult1 = T, TResult2 = never>(
        //  PromisesA+ 2.2.1
        onFulfilled?: ((value: T | PromiseLike<T>) => TResult1 | PromiseLike<TResult1>) | undefined | null,
        onRejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null
    ): MyPromise<TResult1 | TResult2> {
        //  PromisesA+ 2.2.5 | PromisesA+ 2.2.7.3 | PromisesA+ 2.2.7.4
        onFulfilled = typeof onFulfilled === "function" ? onFulfilled : (val: T | PromiseLike<T>) => val as any;
        onRejected =
            typeof onRejected === "function"
                ? onRejected
                : (r: any) => {
                      throw r;
                  };
        //  PromisesA+ 2.2.7
        const promise2 = new MyPromise<TResult1 | TResult2>((resolve: Resolve<TResult1 | TResult2>, reject: Reject) => {
            if (this.state === States.FULFILLED) {
                //  PromisesA+ 2.2.2
                //  PromisesA+ 2.2.4 异步调用,用setTimeout模拟创建微任务
                setTimeout(() => {
                    try {
                        //  PromisesA+ 2.2.7.1
                        let x = onFulfilled!(this.value);
                        this.resolvePromise(promise2, x, resolve, reject);
                    } catch (e) {
                        //  PromisesA+ 2.2.7.2
                        reject(e);
                    }
                });
            } else if (this.state === States.REJECTED) {
                //  PromisesA+ 2.2.3
                //  PromisesA+ 2.2.4 异步调用,用setTimeout模拟创建微任务
                setTimeout(() => {
                    try {
                        //  PromisesA+ 2.2.7.1
                        let x = onRejected!(this.reason);
                        this.resolvePromise(promise2, x, resolve, reject);
                    } catch (e) {
                        //  PromisesA+ 2.2.7.2
                        reject(e);
                    }
                });
            } else if (this.state === States.PENDING) {
                //  PromisesA+ 2.2.6
                //  调用回调函数时是异步的,因此这里不再需要加setTimeout
                this.onFulfilledCallbacks.push(() => {
                    try {
                        let x = onFulfilled!(this.value);
                        //  PromisesA+ 2.2.7.1
                        this.resolvePromise(promise2, x, resolve, reject);
                    } catch (e) {
                        reject(e);
                    }
                });
                this.onRejectedCallbacks.push(() => {
                    try {
                        let x = onRejected!(this.reason);
                        //  PromisesA+ 2.2.7.1
                        this.resolvePromise(promise2, x, resolve, reject);
                    } catch (e) {
                        reject(e);
                    }
                });
            }
        });
        return promise2;
    }

    resolvePromise<T>(promise: MyPromise<T>, x: T | PromiseLike<T>, resolve: Resolve<T>, reject: Reject) {
        //  PromisesA+ 2.3.1
        if (promise === x) {
            const e = new TypeError("TypeError: Circular reference");
            reject(e);
        }
        let called = false; //  防止resolve和reject多次调用
        //  PromisesA+ 2.3.3
        if (x && (typeof x === "object" || typeof x === "function")) {
            try {
                //  PromisesA+ 2.3.3.1 | PromisesA+ 2.3.2
                const then = (x as PromiseLike<T>).then;
                if (typeof then === "function") {
                    then.call(
                        x,
                        //  PromisesA+ 2.3.3.3.1
                        (y: T | PromiseLike<T>) => {
                            //  PromisesA+ 2.3.3.3.3
                            if (called) return;
                            called = true;
                            //  直到解析的对象不再是 thenable,取出其中的值
                            this.resolvePromise(promise, y, resolve, reject);
                        },
                        //  PromisesA+ 2.3.3.3.2
                        (r: any) => {
                            //  PromisesA+ 2.3.3.3.3
                            if (called) return;
                            called = true;
                            reject(r);
                        }
                    );
                } else {
                    //  PromisesA+ 2.3.3.4
                    resolve(x);
                }
            } catch (e) {
                //  PromisesA+ 2.3.3.2 | PromisesA+ 2.3.3.3.3 | PromisesA+ 2.3.3.3.4
                if (called) return;
                called = true;
                reject(e);
            }
        } else {
            //  PromisesA+ 2.3.4
            resolve(x);
        }
    }
}

测试流程

测试工具文档:Promises/A+ Compliance Test Suite

为了使用官方工具进行测试,需要在程序的最后添加如下代码:

// @ts-ignore
MyPromise.defer = MyPromise.deferred = function () {
    let deferred: any = {};
    deferred.promise = new MyPromise((resolve, reject) => {
        deferred.resolve = resolve;
        deferred.reject = reject;
    });
    return deferred;
};

// @ts-ignore
export = MyPromise;

将ts代码编译为js

tsc promise.ts

运行测试

npx promises-aplus-tests promise.js

测试结果:测试通过

参考文章

  1. Promise的源码实现(完美符合Promise/A+规范)
  2. 实现一个TS版,符合 Promise/A+规范的 Promise
  开发测试 最新文章
pytest系列——allure之生成测试报告(Wind
某大厂软件测试岗一面笔试题+二面问答题面试
iperf 学习笔记
关于Python中使用selenium八大定位方法
【软件测试】为什么提升不了?8年测试总结再
软件测试复习
PHP笔记-Smarty模板引擎的使用
C++Test使用入门
【Java】单元测试
Net core 3.x 获取客户端地址
上一篇文章      下一篇文章      查看所有文章
加:2022-02-22 20:54:14  更:2022-02-22 20:54:56 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/18 2:58:09-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码