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
到此这篇关于JavaScript面试必考之实现手写Promise的文章就介绍到这了,更多相关JavaScript手写Promise内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!