自定义Promise实现,来了解他的运行原理
function MyPromise(executor) {
// 添加属性
this.promiseState = 'pendding'; // 默认值是pendding
this.promiseResult = null;
// this.callback = {}; // 会存在覆盖的情况
this.callbacks = []; // 应该使用数组去存所有的回调
const self = this;
// resolve函数
function resolve(data) {
// 状态只能改一次
if(self.promiseState =='pendding') {
// 这里的this是window
// 1 修改对象状态promiseState 属于实例对象
self.promiseState = 'fullfilled'
// 2 设置对象结果值promiseResult 属于实例对象
self.promiseResult = data
// 这里执行回调 异步的时候处理, 这里有缺陷,可以有多个回调
// if(self.callback.onResolved) {
// self.callback.onResolved();
// }
// 保证回调时异步执行的
setTimeout(() => {
self.callbacks.forEach(item => {
item.onResolved()
})
})
}
}
// reject函数
function reject(data) {
if(self.promiseState =='pendding') {
// 1 修改对象状态promiseState 属于实例对象
self.promiseState = 'rejected'
// 2 设置对象结果值promiseResult 属于实例对象
self.promiseResult = data
// if(self.callback.onRejected) {
// self.callback.onRejected();
// }
setTimeout(() => {
self.callbacks.forEach(item => {
item.onRejected()
})
})
// self.callbacks.forEach(item => {
// item.onRejected()
// })
}
}
// 这里应该加try-catch, 目的是在抛出错误的时候 同样能够改变状态
try{
// 同步执行executor
executor(resolve, reject); // resolve,和reject是函数内部使用的,因此应该在内部声明
} catch(e) {
// 修改promise对象状态为失败
reject(e);
}
}
// 添加then方法
// MyPromise.prototyep.then = function(onResolved, onRejected) {
// // 调用回调函数,是有条件的通过promiseState 来判断
// if(this.promiseState =='fullfilled') {
// onResolved(this.promiseResult);
// }
// if(this.promiseState == 'rejected') {
// onRejected(this.promiseResult);
// }
// if(this.promiseState == 'pendding') {
// // 保存回调函数, 因为这里状态不确定,不能直接调用回调,应该先保存下来,在状态改变的时候去调用, 因此在实例对象上声明一个属性callback = {}
// // this.callback = { // 这种写法有瑕疵,因为可以指定多个回调,而这种方式会覆盖之前的回调,应该用一个数组去存将this.callback 该为this.callbacks
// // onResolved:onResolved,
// // onRejected: onRejected
// // }
// // 缓存所有的回调
// this.callbacks.push({
// onResolved:onResolved,
// onRejected: onRejected
// })
// }
// }
// then方法应该返回promsie对象, 该实现由很多重复代码,应该优化
// MyPromise.prototyep.then = function(onResolved, onRejected) {
// const self = this;
// return new MyPromise((resolve, reject) => {
// // 调用回调函数,是有条件的通过promiseState 来判断
// if(this.promiseState =='fullfilled') {
// // 获取回调函数的执行结果
// // 解决抛出异常时改变状态
// try{
// let result = onResolved(this.promiseResult);
// if(result instanceof MyPromise) {
// result.then(v => {
// resolve(v);
// }, r => {
// reject(r)
// })
// } else {
// // 结果的对象状态变为成功
// resolve(result);
// }
// }catch(e) {
// reject(e)
// }
// }
// if(this.promiseState == 'rejected') {
// // 解决抛出异常时改变状态
// try{
// let result = onRejected(this.promiseResult);
// if(result instanceof MyPromise) {
// result.then(v => {
// resolve(v);
// }, r => {
// reject(r)
// })
// } else {
// // 结果的对象状态变为成功
// resolve(result);
// }
// }catch(e) {
// reject(e)
// }
// }
// if(this.promiseState == 'pendding') {
// // 保存回调函数, 因为这里状态不确定,不能直接调用回调,应该先保存下来,在状态改变的时候去调用, 因此在实例对象上声明一个属性callback = {}
// // this.callback = { // 这种写法有瑕疵,因为可以指定多个回调,而这种方式会覆盖之前的回调,应该用一个数组去存将this.callback 该为this.callbacks
// // onResolved:onResolved,
// // onRejected: onRejected
// // }
// // 缓存所有的回调, 异步回调的时候这种写法也有问题
// // this.callbacks.push({
// // onResolved:onResolved,
// // onRejected: onRejected
// // })
// this.callbacks.push({
// onResolved: function() {
// try{
// console.log('success')
// // 执行成功的回调函数,根据其结果改变状态
// let result = onResolved(self.promiseResult)
// if(result instanceof MyPromise) {
// result.then(v => {
// resolve(v);
// }, r => {
// reject(r);
// })
// } else{
// resolve(resulte)
// }
// }catch(e){
// reject(e)
// }
// },
// onRejected: function () {
// try{
// let result = onRejected(self.promiseResult)
// if(result instanceof MyPromise) {
// result.then(v => {
// resolve(v);
// }, r => {
// reject(r);
// })
// } else{
// resolve(resulte)
// }
// }catch(e){
// reject(e);
// }
// }
// })
// }
// })
// }
// 优化then方法
MyPromise.prototyep.then = function(onResolved, onRejected) {
const self = this;
// 判断回调函数
if(typeof onRejected !== 'function') { // 这里给定默认值是因为在发生错误的时候会调用该函数,
onRejected = reason => {
throw reason
}
}
if(typeof onResolved !== 'function') { // 这里给定默认值是因为在发生错误的时候会调用该函数,
onResolved = value => value;
}
return new MyPromise((resolve, reject) => {
// 封装函数
function callback(type) {
try{
let result = type(self.promiseResult);
if(result instanceof MyPromise) {
result.then(v => {
resolve(v);
}, r => {
reject(r)
})
} else {
// 结果的对象状态变为成功
resolve(result);
}
}catch(e) {
reject(e)
}
}
// 调用回调函数,是有条件的通过promiseState 来判断
if(this.promiseState =='fullfilled') {
// 获取回调函数的执行结果
// 解决抛出异常时改变状态
setTimeout(function () {
callback(onResolved)
})
}
if(this.promiseState == 'rejected') {
// 解决抛出异常时改变状态
setTimeout(function () {
callback(onRejected)
})
}
if(this.promiseState == 'pendding') {
// 保存回调函数, 因为这里状态不确定,不能直接调用回调,应该先保存下来,在状态改变的时候去调用, 因此在实例对象上声明一个属性callback = {}
// this.callback = { // 这种写法有瑕疵,因为可以指定多个回调,而这种方式会覆盖之前的回调,应该用一个数组去存将this.callback 该为this.callbacks
// onResolved:onResolved,
// onRejected: onRejected
// }
// 缓存所有的回调, 异步回调的时候这种写法也有问题
// this.callbacks.push({
// onResolved:onResolved,
// onRejected: onRejected
// })
this.callbacks.push({
onResolved: function() {
callback(onResolved)
},
onRejected: function () {
callback(onRejected)
}
})
}
})
}
// 添加catch方法
MyPromise.promiseState.catch = function (onRejected) {
return this.then(undefined, onRejected)
}
// MyPromise.resolve() 快速创建一个promise对象
MyPromise.resolve = function (value) {
return new MyPromise((resolve, reject) => {
if(value instanceof MyPromise) {
value.then(v => {
resolve(v);
}, r => {
reject(r);
})
} else {
// 设置状态为成功
resolve(value)
}
})
}
MyPromise.reject = function (reason){
return MyPromise((reason, reject) => {
reject(reason)
})
}
// Promise.all
MyPromise.all = function (promises) {
return new MyPromise((resolve, reject) => {
let count = 0;
let arr = []; // 存结果
for(let i = 0; i < promises.length; i++) {
promises[i].then(v=>{
// resolve() 这里直接调用不对,应该三个都成功才能resolve
count++;
arr[i] = v;
if(count === promises.length) { // 说明都成功了
resolve(arr);
}
}, r=>{
reject();
})
}
})
}
MyPromise.race = function (promises) {
return MyPromise((resolve, reject) => {
for(let i = 0; i < promises.length; i++) {
promises[i].then(v=>{
resolve(v); // 谁先运行谁先决定结果
}, r=>{
reject();
})
}
})
}
网友评论