拆解 Promise 的使用:
- 在使用一个 Promise 的时候,需要通过一个 new 关键字来创建一个 Promise 对象;
new Promise();
在创建完成之后,可以看出这个 Promise 就是一个类(MDN参考:developer.mozilla.org/zh-CN/docs/… )
- 在执行这个类的时候,需要传递一个回调函数进来,这个回调函数会立即执行(见下图)。也就是说在创建了 Promise 之后,这个回调函数是会被立即执行的(这好像是句废话)。
new Promise(() => {});
- 在使用 Promise 的时候会向里面传递两个参数:resolve,reject;调用这两个参数的时候会更改 Promise 的状态,所以这两个参数实际上是两个函数。
new Promise((resolve, reject) => {});
- Promise 的状态:等待 pending; 失败 rejected; 成功 fulfilled;
new Promise(() => {
resolve('成功');
// reject('失败');
});
// Promise 的状态改变:一旦状态确定就不可更改
// resolve 被调用时将状态会更改为成功:pending -> fulfilled
// reject 被调用时将状态会更改为失败:pending -> rejected
PS:是不是好奇凭啥 resolve 出来的就是成功,reject 出来的就是失败,反过来用不行么? 我觉得行!但是没招儿,这甲鱼的屁股--规定!
- 在使用 Promise 的时候还可以将 Promise 执行的结果赋值给一个变量,在这里还可以调用 Promise 的方法 then;由此可见 then 方法里面干了一件事儿,就是判断了当前这个 Promise 的状态,如果是成功就调用成功的回调,如果是失败就调用失败的回调
let promise = new Promise(() => {
resolve('成功');
// reject('失败');
});
// 调用 Promise 的方法 then;成功 失败
promise.then(() => {}, () => {});
- then 方法成功回调有一个参数,表示成功的值,失败同样也有一个参数,表示失败的原因
let promise = new Promise(() => {
resolve('成功');
// reject('失败');
});
// 调用 Promise 的方法 then;成功传递成功的值,失败传递失败的原因
promise.then(value => {}, reason => {});
拆解分析结束,开始实现一个 Promise
- 既然 Promise 是一个类,那就用 class 关键字来创建一个类
class myPromise {}
- 在这个类执行的时候,需要传递回调函数进来,所以这里通过构造函数 constructor 来接收这个回调函数。
class myPromise {
constructor(executor) {
executor();
}
}
- 在这个回调函数被调用的时候又传递了resolve函数, reject函数
class myPromise {
constructor(executor) {
executor(this.resolve, this.reject);
}
// Q: 为啥要写成箭头函数?
// A1: 这两个函数在被调用的时候是直接被调用的,如果这两个函数是一个普通函数的情况下,这两个函数里面的 this 就指向了 window 或者 undefined;
// A2: 定义为箭头函数就是让 this 的指向就指向当前的实例对象,也就是创建的这个 Promise 对象
resolve = () => {};
reject = () => {};
}
- 当调用 resolve 的时候需要将 Promise 的状态更改为成功,当调用 reject 的时候需要将 Promise 的状态更改为失败。
// 更改状态就要有状态 (真理啊!)
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'reiected';
// Q: 为啥定义成常量? // A: 频繁使用方便复用
class myPromise {
constructor(executor) {
executor(this.resolve, this.reject);
}
// 因为这个状态是每一个 Promise 独有的状态,所以在这里定义成一个实例属性
status = PENDING;
resolve = () => {
// 将状态更改为成功
this.status = FULFILLED;
};
reject = () => {
// 将状态更改为失败
this.status = REJECTED;
};
}
PS: 凭啥 resolve 就得是成功,就让 reject 是成功不行么?都自己写了还不能做主?行!可以!没问题!写程序嘛,开心就好。
- Promise 状态一经更改就不能再次改变,按照上面的写法调用了成功回调之后紧接着调用失败回调,那么这个成功又失败了,所以这个实现是存在问题的(白给,写了一堆还有问题,这是写了个寂寞啊)为了防止它在成功和失败之间反复横跳,更改这个状态的时候给它加个判断试试
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'reiected';
class myPromise {
constructor(executor) {
executor(this.resolve, this.reject);
}
status = PENDING;
resolve = () => {
if (this.status !== PENDING) return;
this.status = FULFILLED;
};
reject = () => {
if (this.status !== PENDING) return;
this.status = REJECTED;
};
}
- 既然每一个 Promise 对象都可以调用 then 方法,它应该是存在于原型对象上的
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'reiected';
class myPromise {
constructor(executor) {
executor(this.resolve, this.reject);
}
status = PENDING;
resolve = () => {
if (this.status !== PENDING) return;
this.status = FULFILLED;
};
reject = () => {
if (this.status !== PENDING) return;
this.status = REJECTED;
};
// 定义 then 方法用来判断状态
then (successCallback, failCallback) => {
if (this.status === FULFILLED) {
successCallback();
} else if (this.status === REJECTED) {
failCallback();
}
};
}
- 当调用成功回调的时候应该传递成功的值,当调用失败回调的时候应该传递失败的原因
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'reiected';
class myPromise {
constructor(executor) {
executor(this.resolve, this.reject);
}
status = PENDING;
// 成功和失败,默认情况下是没有的,所以值应该是 undefined
value = undefined;
reason = undefined;
// 接收成功的值
resolve = value => {
if (this.status !== PENDING) return;
this.status = FULFILLED;
// 保存成功之后的值
this.value = value;
};
// 接收失败的原因
reject = reason => {
if (this.status !== PENDING) return;
this.status = REJECTED;
// 保存失败之后的原因
this.reason = reason;
};
then (successCallback, failCallback) => {
if (this.status === FULFILLED) {
successCallback(this.value);
} else if (this.status === REJECTED) {
failCallback(this.reason);
}
};
}
- 到此为止一个极其简化版的 Promise 就酱婶儿完成了。
接下来实现的是 Promise 关于异步的部分
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!