Promise/A+ 是 Promise 最小的一个规范,它包括:npm
1 promise状态
2 then方法
3 promise解析过程
任何能跑通测试的 Promise 实现都被 Promise/A+ 承认。promise
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 } } //导出咱们本身写的promise module.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.在当前文件夹下执行this
promises-aplus-tests xxx.js(本身写promise的文件)