
实现手写promise,列举几个关键点:
- 构造函数的resolve 或是 reject的value值,可能是Promise的实例,不是普通的值,需要再次调用then方法
- then方法一定会返回一个新的promise
- 处理resolve,reject函数返回值的时候,一定是迭代递归,直到是普通值为止
/*** @author lihh* @desc 用来递归不断的new promise.then的* @param p 调用的实例* @param x 返回值* @param resolve 成功的回调* @param reject 失败的回调* @returns {*}*/function nextPromise(p, x, resolve, reject) {if (p === x) {return reject(new TypeError('循环引用'))}// 判断是否是对象 以及函数 如果上述两者以外的 直接就按普通值来处理if ((x && typeof x === 'object') || typeof x === 'function') {let called = falsetry {const then = x.then// 判断是否是函数 如果不是函数 直接按普通值处理if (typeof then === 'function') {// 开始调用thenthen.call(x,(y) => {if (called) returncalled = true// 有可能then 的返回值还是promise,所以继续调用nextPromise 直到是普通值的时候nextPromise(p, y, resolve, reject)},(r) => {if (called) returncalled = truenextPromise(p, r, resolve, reject)})} else {resolve(x)}} catch (e) {if (called) returncalled = truereject(e)}} else {resolve(x)}}// promise的几种状态const promiseStatus = {pending: 'pending',fulfilled: 'fulfilled',rejected: 'rejected',}class Promise1 {constructor(execute) {// 成功的返回值this.value = ''// promise的状态this.state = promiseStatus.pending// 失败的原因this.reason = ''// 延时时,成功的回调函数this.resolveCallback = []// 延时时,失败的回调函数this.rejectCallback = []// 成功的回调const onFulfilledHandle = (value) => {if (this.state !== promiseStatus.pending) return// 如果传递的数据是promise实例 再次调用then 做特殊处理if (value instanceof Promise1) {return value.then(onFulfilledHandle, onRejectedHandle)}this.state = promiseStatus.fulfilledthis.value = valueif (this.resolveCallback.length > 0) {let fnwhile ((fn = this.resolveCallback.shift())) {fn(this.value)}}}// 失败的回调const onRejectedHandle = (reason) => {if (this.state !== promiseStatus.pending) returnif (reason instanceof Promise1) {return reason.then(onFulfilledHandle, onRejectedHandle)}this.state = promiseStatus.rejectedthis.reason = reasonif (this.rejectCallback.length > 0) {let fnwhile ((fn = this.rejectCallback.shift())) {fn(this.reason)}}}try {// 立即执行传递的构造函数execute(onFulfilledHandle, onRejectedHandle)} catch (e) {// 异常的时候 直接调用错误信息onRejectedHandle(e)}}// then 会返回一个全新的promisethen(onFulfilled, onRejected) {// 传递的then 有可能两个函数都没有 所以需要做特殊处理onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : (x) => xonRejected =typeof onRejected === 'function'? onRejected: (err) => {throw err}let x// 如果状态还是等待中 说明是异步if (this.state === promiseStatus.pending) {const p2 = new Promise1((resolve, reject) => {this.resolveCallback.push((...args) => {try {x = onFulfilled(...args)nextPromise(p2, x, resolve, reject)} catch (e) {reject(e)}})this.rejectCallback.push((...args) => {try {x = onRejected(...args)nextPromise(p2, x, resolve, reject)} catch (e) {reject(e)}})})return p2}const p = new Promise1((resolve, reject) => {try {if (this.state === promiseStatus.fulfilled) {x = onFulfilled(this.value)}if (this.state === promiseStatus.rejected) {x = onRejected(this.reason)}nextPromise(p, x, resolve, reject)} catch (e) {reject(e)}})return p}catch(callback) {return this.then(null, callback)}// 全部执行结束 才算结束static all(arr) {const result = []let len = 0return new Promise1((resolve, reject) => {const callback = (i, res) => {result[i] = reslen++if (len === arr.length) {resolve(result)}}let item = nullfor (let i = 0; i < arr.length, (item = arr[i]); i++) {if (item instanceof Promise1) {item.then((res) => {callback(i, res)}, reject)} else {callback(i, item)}}})}// 无论是成功的 还是 失败的 都会进行返回static allSettled(arr) {let len = 0const result = []return new Promise1((resolve, reject) => {const callback = (i, value, status) => {result[i] = { status, value }len++if (len === arr.length) {resolve(result)}}let itemfor (let i = 0; i < arr.length, (item = arr[i]); i++) {if (item instanceof Promise1) {item.then((x) => {callback(i, x, 'fulfilled')},(y) => {callback(i, y, 'rejected')})} else {callback(i, item, 'fulfilled')}}})}// 谁执行的快 返回谁static race(arr) {return new Promise1((resolve, reject) => {let itemfor (let i = 0; i < arr.length, (item = arr[i]); i++) {if (item instanceof Promise1) {item.then(resolve, reject)} else {resolve(item)}}})}// 直接返回promise的失败的状态static reject(value) {return new Promise1((resolve, reject) => {reject(value)})}// 直接返回promise的成功态static resolve(value) {return new Promise1((resolve) => {resolve(value)})}// 如果有成功的状态 直接返回第一个成功的状态 如果都不成功的话 返回第一个失败的状态static any(arr) {const failResult = []let len = 0return new Promise1((resolve, reject) => {const callback = (status, value) => {len++if (status === 'fulfilled') {resolve(value)} else {failResult.push(value)}if (len === arr.length) {resolve(failResult[0])}}let itemfor (let i = 0; i < arr.length, (item = arr[i]); i++) {item.then((x) => {callback('fulfilled', x)},(y) => {callback('rejected', y)})}})}}module.exports = Promise1
