1.0什么是Promise?
2.0 如何实现一个Promise
2.1 初步实现promise
Promise的特点:
- 有三种状态,默认是pending,成功为fulfilled,失败为rejected
- 创建时必须传递一个函数,不然会报错
- 传递函数中参数是两个回调函数,resolve和reject
- 状态一旦发生改变就不会发生变化
class MyPromise{
//有一个构造器
constructor(fn) {
//这个构造器要判断接收进来的是不是一个函数
if (!this.isFun(fn)){
throw new Error('这不是一个函数');
}
//1.定义默认状态
this.status = 'pending';
//2.函数参数fn中有两个回调函数resolve、reject
//2.1调用resolve就改变status为fulfilled
this.resolve = (data)=>{
//状态一旦发生改变就不会在改变,所以在这里判断下是否为默认状态
if (this.status === 'pending'){
this.status ='fulfilled';
console.log('fulfilled');
}
}
//2.1调用reject就改变status为rejected
this.reject = (data)=>{
//这里的判断是因为status改变了就不能再改变
if (this.status === 'pending'){
this.status = 'rejected';
console.log('rejected');
}
}
fn(this.resolve,this.reject);
}
//判断fn是是否是一个函数
isFun(fn){
return typeof fn === 'function';
}
}
let case = new MyPromise(function (resolve,reject) {
resolve();
});
console.log(case);
输出结果:
//调用resolve()
//调用reject()
let case = new MyPromise(function (resolve,reject) {
reject();
});
console.log(case);
//重复调用
let a = new MyPromise(function (resolve,reject) {
resolve();
reject();
});
console.log(a);
//说明status的状态一旦被改变就不能再被改变
//传入非函数参数:
let a = new MyPromise([1,2,3]);
console.log(a);
2.2 实现primose实例的then方法
Promise的特点:
- 同一个promise对象可以添加多个then监听,状态改变时会按照监听顺序依次执行
- then方法每次执行完毕会返回一个新的promise对象
- 上一个Promise对象的then方法可以给返回的新的Promise的then传递参数
- 无论上一个是在then成功或者失败的回调中传参,都会传递给新的Promise对象then方法中成功的回调
- 如果上一个传递的是一个Promise对象,那么传给下一个的成功还是失败由传递的Promsie状态决定
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>手写promise</title>
</head>
<body>
<script>
class MyPromise{
//有一个构造器
constructor(fn) {
//这个构造器要判断接收进来的是不是一个函数
if (!this.isFun(fn)){
throw new Error('这不是一个函数');
}
this.status = 'pending';
//定义两个属性保持resolve和reject中的参数
this.value = undefined;
this.fail = undefined;
//存放成功的数组
this.onSuccessCallbacks = [];
//存放失败的数组
this.onFailCallbacks = [];
//函数参数中有两个回调参数,resolve和reject
this.resolve = (data)=>{
//状态一旦发生改变就不会在改变,所以在这里判断下是否为默认状态
if (this.status === 'pending'){
this.status ='fulfilled';
this.value = data;
if (this.onSuccessCallbacks){
this.onSuccessCallbacks.forEach((fn) =>{
fn(this.value)
})
}
// console.log('fulfilled');
}
}
//2.1调用reject就改变status为rejected
this.reject = (data)=>{
//这里的判断是因为status改变了就不能再改变
if (this.status === 'pending'){
this.status = 'rejected';
this.fail = data;
if (this.onFailCallbacks){
this.onFailCallbacks.forEach((fn)=>{
fn(this.fail);
})
}
// console.log('rejected');
}
}
fn(this.resolve,this.reject);
}
//then方法、有两个参数、成功回调和失败回调
then(onSuccess,onFail){
//每次执行then方法都会返回一个新的Promise实例
return new MyPromise((nextSuccess,nextFail)=>{
//成功或者失败的回调也必须是个函数
if (this.isFun(onSuccess)){
//只有状态改变才会执行
if (this.status === 'fulfilled'){
//因为then中可以拿到resolve和reject中传递的参数
//then中也可以return一个Promise
//那么传给下一个的成功还是失败由传递的promise状态决定
let res = onSuccess(this.value);
//判断返回的是否是个promise对象
if(res instanceof MyPromise){
res.then(nextSuccess,nextFail);
}else if (res!== undefined){
nextSuccess(res);
}else {
nextSuccess();
}
}
}
if (this.isFun(onFail)){
if (this.status === 'rejected'){
let res = onFail(this.fail);
if (res instanceof MyPromise){
res.then(nextSuccess,nextFail);
}else if (res !== undefined){
nextSuccess(res);
}else {
nextFail();
}
}
}
//解决延迟回调问题,因为可能你会在promise中放一个定时器
if (this.status === 'pending'){
if (this.isFun(onSuccess)){
//将then中要执行的回调都保持到一个数组中,当状态改变时依次执行
this.onFailCallbacks.push(()=>{
let res = onSuccess(this.value);
if (res instanceof MyPromise){
res.then(nextSuccess,nextFail)
}else if (res!==undefined){
nextSuccess(res);
}else {
nextSuccess();
}
})
}
}
if (this.isFun(onFail)){
this.onFailCallbacks.push(()=>{
let res = onFail(this.fail);
if (res instanceof MyPromise){
res.then(nextSuccess,nextFail)
}else if(res !==undefined){
nextSuccess(res);
}else{
nextFail();
}
})
}
})
}
//判断fn是是否是一个函数
isFun(fn){
return typeof fn === 'function';
}
}
let a = new MyPromise(function (resolve,reject) {
setTimeout(()=>{
//resolve('xyz')
reject('xyz');
},1000)
console.log('执行了');
});
a.then(function (data) {
console.log(data,'success');
},function (data) {
console.log(data,'fail');
})
</script>
</body>
</html>
持续更新……