最近了解了下Promise,手动实现一下。
// 放到自执行函数中,挂载到window上
! (function (window) {
const PENDING = 'pending';
const RESOLVED = 'resolved';
const REJECTED = 'rejected';
function Promise(executor) {
const self = this;
self.data = undefined;
self.status = PENDING;
self.callbacks = [];
function resolve(value) {
// 如果状态不是 Pending直接return
if (self.status !== PENDING) {
return;
}
// 执行此方法时,将状态改为resolved;
self.status = RESOLVED;
// 保存数据
self.data = value;
// 如果有待执行的回调函数,立即异步执行onResolved
if (self.callbacks.length) {
setTimeout(() => {
self.callbacks.forEach(item => {
item.onResolved(value)
})
}, 0)
}
}
function reject(reason) {
// 如果状态不是 Pending直接return
if (self.status !== PENDING) {
return;
}
// 执行此方法时,将状态改为rejected
self.status = REJECTED;
// 保存数据
self.data = reason;
// 如果有待执行的回调函数,立即异步执行onRejected
if (self.callbacks.length) {
setTimeout(() => {
self.callbacks.forEach(item => {
item.onRejected(reason)
})
}, 0)
}
}
// 执行器函数同步执行
try {
executor(resolve, reject);
} catch (error) { // 如果抛出异常执行reject修改状、态
reject(error)
}
}
// 实例方法then 返回新的promise
Promise.prototype.then = function (onResolved, onRejected) {
const self = this;
// 如果传入的onResolved不是方法,那么把值继续往后传
onResolved = typeof onResolved === 'function' ? onResolved : value => value;
// 如果传入的onRejected不是方法,并且调用了onRejected,说明Promise失败了,直接抛出异常 被catch()
onRejected = typeof onRejected === 'function' ? onRejected : reason => {
throw reason
};
// 返回新的promise对象
return new Promise((resolve, reject) => {
// 封装一个方法来应对获取promise的结果的情况。根据执行结果,改变return的promise状态
function getResult(callback) {
try {
const result = callback(self.data);
// 3.如果返回的是promise,那么新的promise的状态就取决于这个promise的结果
// 这个结果怎么得到呢? .then()嘛
if (result instanceof Promise) {
// 当promise的结果为成功时,调用resolve,使新的promise也成功
// 当promise的结果为失败时,调用reject,使新的promise也失败
result.then(resolve, reject)
} else { // 2.如果返回不是promise,那么新的promise是成功状态,value就是返回的这个值
resolve(result)
}
} catch (e) { // 1.如果抛出异常,结果就失败 意味着调用reject
reject(e)
}
}
// 如果是pending状态,那么将待执行的回调函数扔到队列里,但是并没有改变状态。所以直接存起来是不行的,
// 还得调用onResolved,onRejected 来改变状态,
if (self.status === PENDING) {
self.callbacks.push({
onResolved() {
getResult(onResolved)
},
onRejected() {
getResult(onRejected)
}
})
} else if (self.status === RESOLVED) { // resolved状态,调用onResolved
setTimeout(() => {
getResult(onResolved)
})
} else { // rejected状态,调用onRejected
setTimeout(() => {
getResult(onRejected)
})
}
})
};
// 实例方法catch
Promise.prototype.catch = function (onRejected) {
return this.then(undefined, onRejected)
};
// 函数的resolve方法
Promise.resolve = function (value) {
return new Promise((resolve, reject) => {
if (value instanceof Promise) {// value是promise.那就可以.then();得到他的结果
value.then(resolve, reject)
} else { // value不是Promise
resolve(value)
}
})
};
// 函数的reject方法
Promise.reject = function (reason) {
// 返回一个失败的promise
return new Promise((resolve, reject) => {
reject(reason)
})
};
// 函数的all方法
Promise.all = function (promises) {
const results = new Array(promises.length);
let resolveCount = 0;
return new Promise((resolve, reject) => {
promises.forEach((item, index) => {
item.then(
// 成功的就存起来
value => {
resolveCount++; // 成功数+1
results[index] = value;
// 如果全成功了就返回成功的Promise
if (resolveCount === promises.length) {
resolve(results)
}
},
// 只要有一个失败了,那么返回的就是失败的promise
reason => reject(reason)
)
})
})
};
// 函数的race方法
Promise.race = function (promises) {
// 返回一个Promise
return new Promise((resolve, reject) => {
promises.forEach(item => {
item.then(
value => {
resolve(value)
},
reason => {
reject(reason)
}
)
})
})
};
// 函数的resolveDelay方法
Promise.resolveDelay = function(value,time){
return new Promise((resolve,reject) => {
setTimeout(()=>{
resolve(value)
},time)
})
};
// 函数的rejectDelay方法
Promise.rejectDelay = function(reason,time){
return new Promise((resolve,reject) => {
setTimeout(()=>{
reject(reason)
},time)
})
};
window.MyPromise = Promise
})(window);