promise/a+规范概念

Promise/A+ 是 Promise 最小的一个规范,它包括:

1 promise状态
2 then方法
3 promise解析过程

任何能跑通测试的 Promise 实现都被 Promise/A+ 认可。

promise/a+出现的原因

1 我们不知道异步请求什么时候返回数据,所以我们就需要些回调函数。但是在某些情况下我们需要知道数据是在什么时候返回的,然后进行一些处理。
2 当我们在异步回调里面处理的操作还是异步操作的时候,这样就形成了异步回调的嵌套

那么我们就按照这个文档来写一个可通过测试的promise吧(https://www.ituring.com.cn/ar... 写之前最好读几遍规范内容。话不多少,上代码,为了更好的展示我给代码打了很多注释,虽然很乱但是挺清楚的

//规范三种状态,默认是pending;定义宏变量是为了书写时方便一点const PENDING = 'pending';const FULFILLED = 'fulfilled';const REJECTED = 'rejected';function resolvePromise(promise2, x, resolve, reject) {`如果promise和x指向同一对象,以TypeError为据因拒绝执行promise`    if (promise2 === x) {        reject(new TypeError('Chaining cycle detected for promise #<Promise>--'))    }    let called;    `判断如果是对象或者函数`    if ((typeof x === 'object' && x != null) || typeof  x === 'function') {          try {        `文档规定`            let then = x.then;            if (typeof then === 'function') {            `如果then是函数,将x作为函数的作用域this调用之,传递两个回调函数作为参数`                then.call(x, y => {                `防止重复调用`                    if (called) return;                    called = true;                    `如果是嵌套的promise那么需要递归遍历到普通值为止`                    resolvePromise(promise2, y, resolve, reject)                }, r => {                 `防止重复调用`                    if (called) return;                    called = true;                    reject(r)                })            } else {          `如果then不是函数,以x为参数执行promise`                resolve(x)            }        } catch (e) {         `防止重复调用`            if (called) return;            called = true;            `如果取x.then的值时抛出错误e,则以e为据因拒绝promise`            reject(e)        }    } else {    `如果是普通值`        resolve(x)    }}`创建一个promise类`class Promise {    constructor(executor) {        this.status = PENDING;        this.value = undefined;        this.reason = undefined;        this.onFulfilledCallbacks = [];        this.onRejectedCallbacks = [];        `定义executor(resolve, reject)中的resolve,参数value`        let resolve = value => {        `只有状态为pending的情况下才能转换状态`            if (this.status === PENDING) {            `调用reslove函数 状态变为成功态`                this.status = FULFILLED;                `定义变量接受传进来的参数`                this.value = value;                `遍历成功事件池中的方法并依次执行(解决异步)`                this.onFulfilledCallbacks.forEach(fn => fn())            }        };      `定义executor(resolve, reject)中的reject,参数reason`        let reject = reason => {       `只有状态为pending的情况下才能转换状态`            if (this.status === PENDING) {              `调用reject函数 状态变为失败态`                this.status = REJECTED;                `定义变量接受传进来的参数`                this.reason = reason;                `遍历失败事件池中的方法并依次执行(解决异步)`                this.onRejectedCallbacks.forEach(fn => fn())            }        };        try {         `默认传进一个函数executor,并且执行,promise中的提供两个函数`            executor(resolve, reject)        } catch (e) {        `如果抛错调用reject(文档写的)`            reject(e)        }    }    then(onFulfilled, onRejected) {    `(成功态)连续调用时如果函数没有写给他附一个默认值继续向下传递`        onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : d => d;         `(失败态)如果函数没有写,那就把错误抛出去`        onRejected = typeof onRejected === 'function' ? onRejected : e => {            throw e        };        `规范上写调用.then时必须返回promise`        let promise2 = new Promise((resolve, reject) => {        `如果状态为成功态`            if (this.status === FULFILLED) {                setTimeout(() => {                    try {                    `接受.then后面第一个函数的返回值,为了判断有没有抛错使用了try包裹`                        let x = onFulfilled(this.value);                        `判断x是promise还是普通值,从而进行不同的处理,当调用这个函数时获取不到promise所以这里使用了异步`                        resolvePromise(promise2, x, resolve, reject)                    } catch (e) {                    `如果抛错之后调用reject方法以e作为原因`                        reject(e)                    }                }, 0);            }            if (this.status === REJECTED) {                setTimeout(() => {                    try {                        let x = onRejected(this.reason);                        resolvePromise(promise2, x, resolve, reject)                    } catch (e) {                        reject(e)                    }                }, 0);            }            if (this.status === PENDING) {          `如果是异步的话,使用发布订阅模式,将事件放到对应的事件池中`                this.onFulfilledCallbacks.push(() => {                    setTimeout(() => {                        try {                            let x = onFulfilled(this.value);                            resolvePromise(promise2, x, resolve, reject)                        } catch (e) {                            reject(e)                        }                    }, 0)                });                this.onRejectedCallbacks.push(() => {                    setTimeout(() => {                        try {                            let x = onRejected(this.reason);                            resolvePromise(promise2, x, resolve, reject)                        } catch (e) {                            reject(e)                        }                    }, 0)                })            }        });        return promise2;//返回一个promise    }}//导出我们自己写的promisemodule.exports = Promise;

测试

1.安装测试脚本

npm i -g promises-aplus-tests

2.在我们写的promise中写入代码

//测试代码Promise.defer = Promise.deferred = function () {    let dfd = {};    dfd.promise = new Promise((resolve, reject) => {        dfd.resolve = resolve;        dfd.reject = reject;    })    return dfd}

3.在当前文件夹下执行

promises-aplus-tests xxx.js(自己写promise的文件)