前一阵跟着B站老师写了写promise,今天再一想,啥印象也没了。
要是面试问这个,直接蒙圈,玩儿完!
啥东西,不用,就忘。在这先记下来,有空再看。
// 引入该文件之后,直接覆盖内置的promise
//1.声明构造函数,用excutor做形参
function Promise(excutor) {
//4.为实例对象添加属性
this.PromiseState = 'pending'
this.PromiseResult = null;
//8.2 为了执行器函数中的同步改为异步,需要将then中的两个回调存储在一个对象里
//9 将callback改为数组类型,以解决多个回调的情况
this.callback = [];
//5.保存实例对象this的值
let self = this;
// 3、excutor有两个函数参数,分别是resolve(),reject()
function resolve(data) {
//6. promise的状态只能更改一次,所以对当前状态先做判断
if (self.PromiseState !== 'pending') return;
//5.1修改对象的状态和值
self.PromiseState = 'resolved';
self.PromiseResult = data;
// 8.3 调用成功的回调函数
// if (self.callback.onResolved) {
// // self.callback.onResolved(data)
// }
//9 以解决多个回调的情况
setTimeout(() => {
self.callback.forEach(item => {
item.onResolved(data)
})
})
}
function reject(data) {
// 6.promise的状态只能更改一次,所以对当前状态先做判断
if (self.PromiseState !== 'pending') return;
//5.1修改对象的状态和值
self.PromiseState = 'rejected';
self.PromiseResult = data;
// 8.3 调用失败的回调函数
// if (self.callback.onRejected) {
// // self.callback.onRejected(data)
// }
//9 以解决多个回调的情况
setTimeout(() => {
self.callback.forEach(item => {
item.onRejected(data)
})
})
}
// 5,处理throw抛的出异常
try {
// 2、同步调用形参执行器函数
excutor(resolve, reject);
} catch (e) {
reject(e)
}
}
//1.1.为构造函数添加then方法
Promise.prototype.then = function(onResolved, onRejected) {
//7.如何对then进行回调
//7.因为resolve状态对应then方法中第一个回调函数;
//reject状态对应then方法中第二个回调函数;
//所以,在调用onResolved和onRejected之前,要先对当前实例对象p的状态做判断
const self = this;
//12 catch方法异常穿透
if (typeof onRejected !== 'function') {
onRejected = reason => {
throw reason;
}
}
//13 catch方法值传递
if (typeof onResolved !== 'function') {
onResolved = value => value
}
return new Promise((resolve, reject) => {
//封装函数,减少重复代码
function callbacks(type) {
try {
let result = type(self.PromiseResult);
//判断
if (result instanceof Promise) {
result.then(v => {
resolve(v)
}, r => {
reject(r)
})
} else {
resolve(result);
}
} catch (e) {
reject(e);
}
};
if (this.PromiseState === 'resolved') {
setTimeout(() => {
callbacks(onResolved);
})
}
if (this.PromiseState === 'rejected') {
// 获取回调函数的执行结果
setTimeout(() => {
callbacks(onRejected);
})
}
//8.1 为了执行器函数中的同步改为异步,
//判断pending状态,保存回调函数
//在得到状态改变的通知后,then方法需要判断究竟调用成功或失败的回调函数
// 将两个函数存放在一个对象中,一一对应构造函数里的相对应的函数
if (this.PromiseState === 'pending') {
//9 以解决多个回调的情况
this.callback.push({
//11异步任务then返回的结果
onResolved: function() {
callbacks(onResolved);
},
//11异步任务then返回的结果
onRejected: function() {
callbacks(onRejected);
}
})
}
})
}
12 catch方法异常穿透:添加catch方法
Promise.prototype.catch = function(onRejected) {
return this.then(undefined, onRejected);
}
// 添加resolve方法封装,注意:resolve不是实例对象的方法,而是构造函数Promise的方法
Promise.resolve = function(value) {
return new Promise((resolve, reject) => {
if (value instanceof Promise) {
value.then(v => {
resolve(v)
}, r => {
reject(r)
})
} else {
resolve(value)
}
})
}
// 添加reject方法
Promise.reject = function(reason) {
return new Promise((resolve, reject) => {
reject(reason)
})
}
//添加promise.all方法(一个promise数组,只有所有的promise都成功返回结果的状态城市成功,
//只要有一个失败就直接失败
Promise.all = function(promises) {
return new Promise((resolve, reject) => {
let count = 0;
let arr = [];
for (let i = 0; i < promises.length; i++) {
promises[i].then(v => {
//想要对象的状态为成功
//则每个promise对象都应成功
count++;
//将当前promise对象成功的结果存入到数组中
arr[i] = v;
//判断
if (count === promises.length) {
//修改状态
resolve(arr)
}
}, r => {
reject(r);
})
}
})
}
//添加promise.race方法,包含n个promise数组
//返回一个新的promise,第一个完成的promise的结果状态就是最终的结果状态
Promise.race = function(promises) {
return new Promise((resolve, reject) => {
for (let i = 0; i < promises.length; i++) {
//数组中的promise,谁先改变状态,那么谁先调then方法,
//最终返回的promise对象的结果也是第一个改变状态的promise的结果
promises[i].then(v => {
resolve(v)
}, r => {
reject(r)
})
}
})
}