【前端进阶】手写PromiseA+

it2025-03-17  13

【前端进阶】手写PromiseA+

简易版(面试可用)升级版

简易版(面试可用)

// PromiseA+ (function () { // Promise类 function Promise(executor) { // 如果实参不是方法 则报错 if (typeof executor !== "function") throw new TypeError(Object.prototype.toString.call(executor) + 'is not a function'); var self = this; // 将实例保存起来 self.PromiseState = "pending"; // promise状态 self.PromiseResult = undefined; // promise结果 self.fulfilledCallback = []; // promise成功事件池 self.rejectedCallback = [] // promise失败事件池 // 统一处理成功/失败 var run = function run(state, value) { // run执行时根据状态不同进行不同处理 // + 状态不为"pending",则表示已更改过状态,则无法进行二次更改 // + 否则立即改变promise状态值与promise结果值 // + 根据状态执行事件池中已储存的事件 if (self.PromiseState !== "pending") return; self.PromiseState = state; self.PromiseResult = value; setTimeout(function () { var arr = self.PromiseState === "fulfilled" ? self.fulfilledCallback : self.rejectedCallback; for (var i = 0; i < arr.length; i++) { var func = arr[i]; if (typeof func === "function") { func(self.PromiseResult) } } }) } // 成功时执行的方法 var resolve = function resolve(value) { run("fulfilled", value) } // 失败时执行的方法 var reject = function reject(value) { run("rejected", value) } // 立即执行执行器函数:如果函数报错,则promise状态变为失败 try { executor(resolve, reject) } catch (err) { reject(err) } } // Promise原型 Promise.prototype = { customize: true, // 是否为自定义 consturctor: Promise, // 改变构造器指向 then: function then(onfulfilled, onrejected) { var self = this; // then执行时根据状态不同进行不同处理 // + 成功则执行传入的第一个函数 // + 失败则执行传入的第二个函数 // + 状态未变更,则将函数分别存入事件池,等待调用 // + 使用timeout是为了将同步变为异步,使事件处理顺序与内置Promise一致 switch (self.PromiseState) { case "fulfilled": setTimeout(function () { onfulfilled(self.PromiseResult) }) break; case "rejected": setTimeout(function () { onrejected(self.PromiseResult) }) break; default: self.fulfilledCallback.push(onfulfilled) self.rejectedCallback.push(onrejected) break; } }, catch: function (params) { } } // 将类暴露至全局,覆盖内置Promise window.Promise = Promise; })()

升级版

完善then的链式调用promise的方法扩展 // PromiseA+ (function () { // Promise类 function Promise(executor) { // 如果实参不是方法 则报错 if (typeof executor !== "function") throw new TypeError(Object.prototype.toString.call(executor) + 'is not a function'); var self = this; // 将实例保存起来 self.PromiseState = "pending"; // promise状态 self.PromiseResult = undefined; // promise结果 self.fulfilledCallback = []; // promise成功事件池 self.rejectedCallback = [] // promise失败事件池 // 统一处理成功/失败 var run = function run(state, value) { // run执行时根据状态不同进行不同处理 // + 状态不为"pending",则表示已更改过状态,则无法进行二次更改 // + 否则立即改变promise状态值与promise结果值 // + 根据状态执行事件池中已储存的事件 if (self.PromiseState !== "pending") return; self.PromiseState = state; self.PromiseResult = value; setTimeout(function () { var arr = self.PromiseState === "fulfilled" ? self.fulfilledCallback : self.rejectedCallback; for (var i = 0; i < arr.length; i++) { var func = arr[i]; if (typeof func === "function") { arr[i](self.PromiseResult) } } }) } // 成功时执行的方法 var resolve = function resolve(value) { run("fulfilled", value) } // 失败时执行的方法 var reject = function reject(value) { run("rejected", value) } // 立即执行执行器函数:如果函数报错,则promise状态变为失败 try { executor(resolve, reject) } catch (err) { reject(err) } } function resolvePromise(promise, x, resolve, reject) { // 防止死循环 if (x === promise) { throw TypeError('传入的值不能与当前promise对象相同') } // 判断是否为方法或对象 // + 如果是则继续判断 // + 如果不是则以成功状态返回x if (x != null && typeof x === "function" || typeof x === "object") { // 如果获取x.then报错,则以错误状态返回错误信息 try { var then = x.then; // 如果x.then是方法,则表示返回结果是一个新的promise,根据新promise的状态返回 // 否则是则以成功状态返回x if (typeof x.then === "function") { then.call(x, function (value) { resolve(value) }, function (reason) { reject(reason) }) } else { resolve(x) } } catch (err) { reject(err) } } else { resolve(x) } } // Promise原型 Promise.prototype = { customize: true, // 是否为自定义 consturctor: Promise, // 改变构造器指向 then: function then(onfulfilled, onrejected) { // 如果第一个参数不是方法,则给与默认方法 直接返回实参 if (typeof onfulfilled !== "function") { onfulfilled = function onfulfilled(value) { return value } } // 如果第二个参数不是方法,则给与默认方法 抛出实参 if (typeof onrejected !== "function") { onrejected = function onrejected(reason) { throw reason } } // self:原始实例 // promise:新返回的实例(resolve/ reject控制它的成功/失败) var self = this; var promise = new Promise(function (resolve, reject) { // then执行时根据状态不同进行不同处理 // + 成功则执行传入的第一个函数 // + 失败则执行传入的第二个函数 // + 状态未变更,则将函数分别存入事件池,等待调用 // + 使用timeout是为了将同步变为异步,使事件处理顺序与内置Promise一致 switch (self.PromiseState) { case "fulfilled": setTimeout(function () { try { var x = onfulfilled(self.PromiseResult); resolvePromise(promise, x, resolve, reject) } catch (err) { reject(err) } }) break; case "rejected": setTimeout(function () { try { var x = onrejected(self.PromiseResult); resolvePromise(promise, x, resolve, reject) } catch (err) { reject(err) } }) break; default: self.fulfilledCallback.push(function (PromiseResult) { try { var x = onfulfilled(PromiseResult); resolvePromise(promise, x, resolve, reject) } catch (err) { reject(err) } }) self.rejectedCallback.push(function (PromiseResult) { try { var x = onrejected(PromiseResult); resolvePromise(promise, x, resolve, reject) } catch (err) { reject(err) } }) break; } }) return promise }, // 相当于第一个参数不传 catch: function (onrejected) { var self = this; return self.then(null, onrejected) } } // 扩展方法 Promise.resolve = function resolve(value) { return new Promise(function (resolve) { resolve(value) }) } Promise.reject = function reject(reason) { return new Promise(function (_, reject) { reject(reason) }) } // 将类暴露至全局,覆盖内置Promise window.Promise = Promise; })()
最新回复(0)