JavaScript面试必考之实现手写Promise
你也向往长安城吗 人气:0Promise手写
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
加载全部内容