JavaScript面试必考之实现手写Promise

Promise手写

Promise作为面试必考题,Promise的手写也是面试官必问的问题,所以对于Promise我们一定要了解透彻

框架

(function(window) {
 
 MyPromise.prototype.then = function (onResolved, onRejected) {}
 MyPromise.prototype.catch = function (onRejected) {}
 
 function MyPromise(executor){

 function resolve(value){}

 function reject(error){}

 try{
 executor(resolve, reject)
 }catch(error){
 reject(error)
 }
 }

 window.MyPromise = MyPromise
}(window))

完整代码

(function (window) {
 //将.then,.catch方法挂载在MyPromise原型上
 MyPromise.prototype.then = function (onResolved, onRejected) {//.then接受两个回调函数,resolved状态和rejeced状态

 // .then返回一个promise对象
 return new MyPromise((resolve, reject) => {
 let self = this;

 if (self.status === 'pending') {//如果MyPromise状态为pending,将两个回调函数push进回调数组中等待

 this.callbacks.push({ onResolved, onRejected })

 } else if (self.status === 'resolved') { //如果MyPromise状态为resolved,将onResolved直接调用
 setTimeout(() => {
 //检查.then中的回调有没有return返回值
 const result = onResolved(self.data)

 //如果没有return返回值,默认返回promise对象
 if (result instanceof MyPromise) {
 result.then((res => resolve(res), err => reject(err)))
 return result
 } else {
 resolve(result)
 }
 })
 } else {

 setTimeout(() => {
 onResolved(self.data)
 })
 }
 })

 }
 MyPromise.prototype.catch = function (onRejected) { //.catch接受一个回调函数

 if (this.status === 'pending') {
 // 将回调函数放入callbacks数组中
 this.callbacks.push({ onRejected })
 } else if (this.status === 'rejected') {
 setTimeout(() => {
 onRejected(this.data)
 })

 }
 }

 // MyPromise构造函数接受一个执行函数
 function MyPromise(executor) {
 const self = this;
 self.data = undefined;
 self.callbacks = []
 //设置promise对象初始状态为pending
 self.status = 'pending'
 //执行函数第一个参数为resolve回调
 function resolve(value) {
 //如果状态不是pending,则直接返回
 if (self.status !== 'pending') {
 return
 }

 // 执行resolve,promise对象状态变更
 self.status = 'resolved';

 // 拿到resolve中的值
 self.data = value;

 // 调用callbacks中的回调函数
 if (self.callbacks.length > 0) {
 setTimeout(() => {
 self.callbacks.forEach(callbacksObj => {
 callbacksObj.onResolved(value)
 });
 })
 }
 }

 // 执行函数第二个参数为rejecr回调
 function reject(error) {
 //如果状态不是pending,则直接返回
 if (self.status !== 'pending') {
 return
 }

 // 执行resolve,promise对象状态变更
 self.status = 'rejected';

 // 拿到resolve中的值
 self.data = error;

 // 调用callbacks中的回调函数
 if (self.callbacks.length > 0) {
 setTimeout(() => {
 self.callbacks.forEach(callbacksObj => {
 callbacksObj.onRejected(value)
 });
 })
 }
 }
 //使用try catch捕获错误
 try {
 // 在try内执行执行函数
 executor(resolve, reject)
 } catch (error) {
 // 如果出错,默认执行reject
 reject(error);
 }

 }

 window.MyPromise = MyPromise
 }(window))

测试

resolve

let MyPromiseTest = new MyPromise((resolve, reject) => {
 resolve('resolve')
 })
 MyPromiseTest.then(res => {
 console.log(res);
 })
 
 // resolve
let MyPromiseTest = new MyPromise((resolve, reject) => {
 resolve('resolve');
 })
 MyPromiseTest.then(res => {
 console.log(res);

 })
 .then(res => {
 console.log('我是.then()后面的.then()');
 })
 
 // resolve
 // 我是.then()后面的.then()

reject

let MyPromiseTest = new MyPromise((resolve, reject) => {
 reject('reject')
 })
 MyPromiseTest.catch(err => {
 console.log(err);
 })
 
 // reject
let MyPromiseTest = new MyPromise((resolve, reject) => {
 console.log(a);
 })
 MyPromiseTest.catch(err => {
 console.log('捕获错误' + ':' + err);
 })
 
 // 捕获错误:ReferenceError: a is not defined
作者:你也向往长安城吗

%s 个评论

要回复文章请先登录注册