/*
自定义Promise函数模块
*/
(function(window) {
const PENDING = 'pending';
const RESOLVED = 'resolved';
const REJECTED = 'rejected';
/*
Promise构造函数
excutor:执行器函数(同步执行)
*/
function Promise(excutor) {
const _this = this; // 保证指向Promise对象的this
_this.status = PENDING; // 给Promise对象指定status属性,初始值为pending
_this.data = undefined; // 给Promise对象指定一个用于存储结果数据的属性
_this.callbacks = []; // 每个元素的结构:{ onResolved() {}, onRejected() {} }
function resolve(value) {
//如果当前状态不是pending,则立即结束
if(_this.status !== PENDING) {
return;
}
// 将状态改为resolved
_this.status = RESOLVED;
// 保存value数据
_this.data = value;
// 如果有待执行callback函数,立即异步执行回调函数onResolved
if(_this.callbacks.length > 0) {
setTimeout(() => { // 放入队列中执行所有成功的回调
_this.callbacks.forEach(callbacksObj => {
callbacksObj.onResolved(value)
})
})
}
}
function reject(reason) {
//如果当前状态不是pending,则立即结束
if(_this.status !== PENDING) {
return;
}
// 将状态改为rejected
_this.status = REJECTED;
// 保存reason数据
_this.data = reason;
// 如果有待执行callback函数,立即异步执行回调函数onRejected
if(_this.callbacks.length > 0) {
setTimeout(() => { // 放入队列中执行所有成功的回调
_this.callbacks.forEach(callbacksObj => {
callbacksObj.onRejected(reason)
})
})
}
}
/*
立即同步执行excutor
使用try{}catch{}捕获异常
*/
try {
excutor(resolve, reject)
} catch(error) {
reject(error);
}
}
/*
Promise原型对象的then()
onResolved:成功状态时调用的回调函数
onRejected:失败状态时调用的回调函数
指定成功状态或失败状态时调用的回调函数,返回一个新的Promise对象
*/
Promise.prototype.then = function(onResolved, onRejected) {
// 向后传递成功的value
onResolved = typeof onResolved === 'function' ? onResolved : value => {
value
}
// 向后传递失败的reason
// 抛出异常让try{}cathc{}捕获,指定默认的失败的回调(实现错误/异常穿透的关键点)
onRejected = typeof onRejected === 'function' ? onRejected : reason => {
throw reason
}
const _this = this;
// 返回一个新的promise对象
return new Promise((resolve, reject) => {
//调用指定回调函数处理,根据执行结果,改变return的promise的状态
function handle(callback) {
/*
1.如果抛出异常,return的promise就会失败,reason就是error
2.如果回调函数返回不是promise,return的promise就会成功,value就是返回的值
3.如果回调函数返回是promise,return的promise结果就是这个promise的结果
*/
try {
const result = callback(_this.data);
if(result instanceof Promise) {
// 3.如果回调函数返回是promise,return的promise结果就是这个promise的结果
//当result成功时,让 return的promise也成功
//当result失败时,让 return的promise也失败
// 简便写法
// result.then(resolve, reject);
result.then(
value => resolve(value),
reason => reject(reason)
)
} else {
// 2.如果回调函数返回不是promise,return的promise就会成功,value就是返回的值
resolve(result);
}
} catch(error) {
// 1.如果抛出异常,return的promise就会失败,reason就是error
reject(error);
}
}
if(_this.status === PENDING) {
// 当前状态是pending状态,将回调函数保存起来
_this.callbacks.push({
onResolved() {
handle(onResolved);
},
onRejected() {
handle(onRejected);
}
})
} else if(_this.status === RESOLVED) {
// 当前是resolved状态,异步执行onResolved并改变return的promise状态
setTimeout(() => {
handle(onResolved);
})
} else {
// 当前是rejected状态,异步执行onRejected并改变return的promise状态
setTimeout(() => {
handle(onRejected);
})
}
})
}
/*
Promise原型对象的catch()
onRejected:失败状态时调用的回调函数
指定失败状态时调用的回调函数,返回一个新的Promise对象
*/
Promise.prototype.catch = function(onRejected) {
return this.then(undefined, onRejected);
}
/*
Promise函数对象的resolve方法
返回一个指定value的成功状态的Promise对象
*/
Promise.resolve = function(value) {
// 返回一个成功/失败状态的Promise
return new Promise((resolve, reject) => {
if(value instanceof Promise) {
// value是Promise对象,使用value的结果作为Promise对象的结果
value.then(resolve, reject);
} else {
// value不是Promise对象,=>Promise对象的状态变为成功状态,数据是value
resolve(value);
}
})
}
/*
Promise函数对象的reject方法
返回一个指定reason的失败状态的Promise对象
*/
Promise.reject = function(reason) {
// 返回一个失败状态的Promise对象
return new Promise((resolve, reject) => {
reject(reason);
})
}
/*
Promise函数对象的all方法
promises:Promise对象的数组
返回一个Promise对象,只有当数组中的Promise对象都为成功状态时,才是成功状态,否则为失败状态
*/
Promise.all = function(promises) {
// 创建一个数组,用来保存成功的promise对象
const values = new Array(promises.length);
// 创建一个计数器
let counter = 0;
return new Promise((resolve, reject) => {
// 遍历promises获取每个promise对象
promises.forEach((item, index) => {
promise.resolve(item).then( //传入的数组中,不一定都是promise对象,将其包装成promise对象
value => {
counter++; // 进来就表明是成功状态的promise,计数器加1
// item成功,将成功的value保存到values,并保证顺序和参数顺序相同
values[index] = value;
// 如果全部成功,返回的promise对象就为成功
if(counter == promises.length) {
// 返回数组values
resolve(values);
}
},
reason => { // 只要有一个失败,返回的promise对象就为失败
reject(reason);
}
)
})
})
}
/*
Promise函数对象的race方法
promises:Promise对象的数组
返回一个Promise对象,它的状态等于-->数组中第一个完成的Promise对象的状态
*/
Promise.race = function(promises) {
return new Promise((resolve, reject) => {
// 遍历promises中的promise对象
promises.forEach(item => {
promise.resolve(item).then( //传入的数组中,不一定都是promise对象,将其包装成promise对象
value => { // 一旦有成功的,将返回的promsie对象变为成功状态
resolve(value);
},
reason => { // 一旦有失败的,将返回的promise对象变为失败状态
reject(reason);
}
)
})
})
}
/*
自定义一个Promise函数对象的resolveDelay方法
返回一个promsie对象,它在指定时间后返回结果
time:延时时间
*/
Promise.resolveDelay = function(value, time) {
// 返回一个成功/失败状态的Promise
return new Promise((resolve, reject) => {
setTimeout(() => {
if(value instanceof Promise) {
// value是Promise对象,使用value的结果作为Promise对象的结果
value.then(resolve, reject);
} else {
// value不是Promise对象,=>Promise对象的状态变为成功状态,数据是value
resolve(value);
}
}, time)
})
}
/*
自定义一个Promise函数对象的rejectDelay方法
返回一个promsie对象,它在指定时间后返回失败结果
time:延时时间
*/
Promise.rejectDelay = function(reason, time) {
// 返回一个失败状态的Promise对象
return new Promise((resolve, reject) => {
setTimeout(() => {
reject(reason);
}, time)
})
}
/*
向外暴露Promise函数
*/
window.Promise = Promise
})(window)
自己手搓一个Promise函数
于 2021-07-07 10:08:42 首次发布