手写Promise(包含测试用例)
(1)测试用例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Promise</title>
<!-- 构造函数 -->
<!-- <script src="./Promise.js"></script> -->
<!-- 类 -->
<!-- <script src="./Promise类.js"></script> -->
</head>
<body>
<script>
// 测试then方法
// 创建Promise实例对象
// let p = new Promise((resolve, reject) => {
// // setTimeout(() => {
// resolve('hahaaa');
// // }, 200);
// });
// console.log(p)
// const result = p.then(value => {
// return new Promise((resolve,reject)=>{
// resolve('hahayang');
// })
// }, reason => {
// console.warn(reason);
// // return new Promise((resolve,reject)=>{
// // reject('haha')
// // })
// // return 'ok';
// throw 'error';
// });
// console.log(27,result)
// 测试catch方法
// let p = new Promise((resolve,reject)=>{
// throw '我戳了';
// })
// p.catch(reason => {
// console.warn(reason);
// })
// 测试catch方法(异常穿透)
// let p = new Promise((resolve,reject)=>{
// throw '我戳了';
// })
// p.then()
// .then(value=>{
// console.log(222)
// }).then(value=>{
// console.log(333);
// }).catch(reason=>{
// console.warn(reason,444);
// })
// 测试resolve方法
// const p2 = Promise.resolve('ok')
// console.log(p2)
// 测试reject方法
// const p3_1 = Promise.reject('haha')
// const p3_2 = Promise.reject(Promise.resolve('我是一个粉刷匠'));
// console.log(p3_1);
// console.log(p3_2)
// 测试all方法
// const p4_1 = Promise.resolve('ok');
// const p4_2 = new Promise((resolve,reject)=>{
// setTimeout(() => {
// resolve('success');
// }, 1000);
// })
// const p4_3 = new Promise((resolve,reject)=>{
// setTimeout(() => {
// resolve('我是一个粉刷匠');
// }, 500);
// })
// const p4 = Promise.all([p4_1,p4_2,p4_3]);
// console.log(p4);
// 测试race方法
// const p5_1 = Promise.resolve('ok');
// const p5_2 = new Promise((resolve, reject) => {
// setTimeout(() => {
// resolve('success');
// }, 1000);
// })
// const p5_3 = new Promise((resolve, reject) => {
// setTimeout(() => {
// resolve('我是一个粉刷匠');
// }, 500);
// })
// const p5 = Promise.race([p5_1, p5_2, p5_3]);
// console.log(p5);
// then方法回调异步调用
// let p = new Promise((resolve,reject)=>{
// console.log(111)
// resolve('ok')
// })
// p.then(value=>{
// console.log(222)
// })
// console.log(333)
// 111 333 222(先执行同步代码,后执行异步代码)
</script>
</body>
</html>
(2)构造函数方法
function Promise(executor) {
// 添加属性
this.PromiseState = 'pending';
this.PromiseResult = null;
this.callbacks = [];
const self = this;
// 定义resolve方法
function resolve(data) {
// 判断状态
if (self.PromiseState !== 'pending') return;
// 修改属性值
self.PromiseState = 'fulfilled';
self.PromiseResult = data;
// 调用then方法
setTimeout(() => {
self.callbacks.forEach(item => {
item.onResolved(data);
});
});
}
// 定义reject方法
function reject(reason) {
if (self.PromiseState !== 'pending') return;
self.PromiseState = 'rejected';
self.PromiseResult = reason;
// 调用then方法
setTimeout(() => {
self.callbacks.forEach(item => {
item.onRejected(reason);
})
});
}
// 同步调用执行器函数
try {
executor(resolve, reject);
} catch (error) {
reject(error);
}
}
// 将then方法绑定在Promise原型链上,所有的Promise实例对象都可以调用then方法
// 添加then方法
Promise.prototype.then = function (onResolved, onRejected) {
// this指向调用zhen方法的实例对象(p)
const self = this;
// 如果没有传入onRejected函数,则自定义一个,catch穿透
if (typeof onRejected !== 'function') {
onRejected = reason => {
throw reason
};
}
// 如果没有传入onResolved函数,则自定义一个
if (typeof onResolved !== 'function') {
onResolved = value => value;
}
return new Promise((resolve, reject) => {
// 封装函数
function callback(type) {
try {
// 获取回调函数的执行结果
let result = type(self.PromiseResult);
// 判断回调函数是否是一个Promise对象实例,
if (result instanceof Promise) {
result.then(value => {
resolve(value)
}, reason => {
reject(reason)
})
} else {
// 结果的对象状态为成功
resolve(result);
}
} catch (error) {
reject(error)
}
}
// 调用回调函数
// 成功的回调
if (this.PromiseState === 'fulfilled') {
setTimeout(() => {
callback(onResolved);
});
}
// 失败的回调
if (this.PromiseState === 'rejected') {
setTimeout(() => {
callback(onRejected)
});
}
// 判断pending状态
if (this.PromiseState === 'pending') {
// 可能存在一个或多个p.then。
// 所以将then方法的回调函数存在一个数组中,等reject或resolve方法去调用这些回调函数
this.callbacks.push({
onResolved: function () {
callback(onResolved);
},
onRejected: function () {
callback(onRejected);
}
})
}
})
}
// 添加catch方法
Promise.prototype.catch = function (onRejected) {
this.then(undefined, onRejected);
}
// 添加resolve方法
Promise.resolve = function (value) {
return new Promise((resolve, reject) => {
if (value instanceof Promise) {
value.then(value => {
resolve(value)
}, reason => {
reject(reason)
})
} else {
resolve(value)
}
})
}
// 添加reject方法
Promise.reject = function (reason) {
return new Promise((resolve, reject) => {
reject(reason);
})
}
// 添加all方法(如果全是fulfilled则返回一个数组,数组中存放着PromiseResult。
// 如果存在一个或多个rejected,则返回最早的{异步})
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(value => {
count++;
arr[i] = value;
if (count === promises.length) {
resolve(arr);
}
}, reason => {
reject(reason)
})
}
})
}
// 添加race方法,谁先完成返回谁
Promise.race = function (promises) {
return new Promise((resolve, reject) => {
for (let i = 0; i < promises.length; i++) {
promises[i].then(value => {
resolve(value)
}, reason => {
reject(reason)
})
}
})
}
(3)类方法
class Promise {
// 构造函数
constructor(executor) {
// 添加属性
this.PromiseState = 'pending';
this.PromiseResult = null;
this.callbacks = [];
const self = this;
// 定义resolve方法
function resolve(data) {
// 判断状态
if (self.PromiseState !== 'pending') return;
// 修改属性值
self.PromiseState = 'fulfilled';
self.PromiseResult = data;
// 调用then方法
setTimeout(() => {
self.callbacks.forEach(item => {
item.onResolved(data);
});
});
}
// 定义reject方法
function reject(reason) {
if (self.PromiseState !== 'pending') return;
self.PromiseState = 'rejected';
self.PromiseResult = reason;
// 调用then方法
setTimeout(() => {
self.callbacks.forEach(item => {
item.onRejected(reason);
})
});
}
// 同步调用执行器函数
try {
executor(resolve, reject);
} catch (error) {
reject(error);
}
}
// 添加then方法
then(onResolved, onRejected) {
// this指向调用zhen方法的实例对象(p)
const self = this;
// 如果没有传入onRejected函数,则自定义一个,catch穿透
if (typeof onRejected !== 'function') {
onRejected = reason => {
throw reason
};
}
// 如果没有传入onResolved函数,则自定义一个
if (typeof onResolved !== 'function') {
onResolved = value => value;
}
return new Promise((resolve, reject) => {
// 封装函数
function callback(type) {
try {
// 获取回调函数的执行结果
let result = type(self.PromiseResult);
// 判断回调函数是否是一个Promise对象实例,
if (result instanceof Promise) {
result.then(value => {
resolve(value)
}, reason => {
reject(reason)
})
} else {
// 结果的对象状态为成功
resolve(result);
}
} catch (error) {
reject(error)
}
}
// 调用回调函数
// 成功的回调
if (this.PromiseState === 'fulfilled') {
setTimeout(() => {
callback(onResolved);
});
}
// 失败的回调
if (this.PromiseState === 'rejected') {
setTimeout(() => {
callback(onRejected)
});
}
// 判断pending状态
if (this.PromiseState === 'pending') {
// 可能存在一个或多个p.then。
// 所以将then方法的回调函数存在一个数组中,等reject或resolve方法去调用这些回调函数
this.callbacks.push({
onResolved: function () {
callback(onResolved);
},
onRejected: function () {
callback(onRejected);
}
})
}
})
}
// 添加catch方法
catch (onRejected) {
this.then(undefined, onRejected);
}
// 添加resolve方法
static resolve(value) {
return new Promise((resolve, reject) => {
if (value instanceof Promise) {
value.then(value => {
resolve(value)
}, reason => {
reject(reason)
})
} else {
resolve(value)
}
})
}
// 添加reject方法
static reject(reason) {
return new Promise((resolve, reject) => {
reject(reason);
})
}
// 添加all方法(如果全是fulfilled则返回一个数组,数组中存放着PromiseResult。
// 如果存在一个或多个rejected,则返回最早的{异步})
static all(promises) {
return new Promise((resolve, reject) => {
let count = 0;
let arr = [];
for (let i = 0; i < promises.length; i++) {
promises[i].then(value => {
count++;
arr[i] = value;
if (count === promises.length) {
resolve(arr);
}
}, reason => {
reject(reason)
})
}
})
}
// 添加race方法,谁先完成返回谁
static race(promises) {
return new Promise((resolve, reject) => {
for (let i = 0; i < promises.length; i++) {
promises[i].then(value => {
resolve(value)
}, reason => {
reject(reason)
})
}
})
}
}