模拟promise
基础逻辑
- 创建 promise 实例
- 创建 resolve、reject 更新状态
- 创建 then 方法,能够在状态变更后执行相应的承诺时事件
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';
class MyPromise{
/*
* 创建 promise 实例时立即执行的方法
* 通过构造函数传入一个执行函数,在 new promise((resolve, reject) => {}) 是就能立即执行这个函数
* 将 resolve reject 通过参数传给执行函数,执行函数中使用者实际情况出发 promise 更新状态。
*/
constructor(executor){
executor(this.resolve, this.reject);
}
status = PENDING;
value = '';
reason = '';
successCallbacks = [];
failCallbacks = [];
/*
* 将状态变更为成功
* 1.主要做3件事:1)更新状态为成功,2)保存成功的值,3)执行承诺事件
* 2.因为这个方法是使用者触发的,所以这里使用箭头函数定义,这样this就能指向promise实例
*/
resolve = value => {
if(this.status !== PENDING) return; // 状态一旦变更就固定了
this.status = FULFILLED;
this.value = value;
while (this.successCallbacks.length){
this.successCallbacks.shift()(this.value);
}
}
/*
* 将状态变更为失败
* 1.主要做3件事:1)更新状态为失败,2)保存失败原因,3)执行承诺事件
*/
reject = reason => {
if(this.status !== PENDING) return;
this.status = REJECTED;
this.reason = reason;
while (this.failCallbacks.length){
this.failCallbacks.shift()(this.value);
}
}
/*
* 承诺状态变更后要执的事件
* 1.根据状态,执行相应的成功还是失败回调
* 2.如果当前状态是 pendding,那么就保存成功失败回调,等转态变更后再执行
*/
then(successCallback, failCallback){
if(this.status === FULFILLED){ // 立即未异步执行 resolve
successCallback(this.value);
}else if(this.status === REJECTED){
failCallback(this.reason);
}else if(this.status === PENDING){
this.successCallbacks.push(successCallback);
this.failCallbacks.push(failCallback);
}
}
}
增加链式调用
也就是实现 p.then().then()
这种情况,做法就是 then 方法返回一个新的 promise
- 返回一个新的 promise
- 用上个 promise 回调返回值更新为当前 promise 的 value
- 回调返回是个 promise 处理
then(successCallback, failCallback){
// 参数可选,这样上个 then 参数为空,也会将上个结果保存到当前 promise
successCallback = successCallback ? successCallback : value => value;
failCallback = failCallback ? failCallback: reason => { throw reason };
let p2 = new MyPromise((resolve, reject) => {
if(this.status === FULFILLED){
let result = successCallback(this.value);
resolvePromise(result, resolve, reject);
}else if(this.status === REJECTED){
let result = failCallback(this.reason);
resolvePromise(result, resolve, reject);
}else if(this.status === PENDING){
// 保存成功失败回调需要增加一层,这样就能处理回调返回值
this.successCallbacks.push(() => {
let result = successCallback(this.value);
resolvePromise(result, resolve, reject);
});
this.failCallbacks.push(() => {
let result = failCallback(this.reason);
resolvePromise(result, resolve, reject);
});
}
});
return p2;
}
处理回调是个 promise
function resolvePromise(x, resolve, reject){
if(x instanceof MyPromise){
x.then(resolve, reject);
}else{
resolve(x);
}
}
捕获异常
- 增加一个 catch 方法
- 处理立即执行中的异常和 then 方法回调中的异常(这两都比较容易,直接在原来操作外使用try catch) 处理立即执行中的异常
constructor(executor){
try{
executor(this.resolve, this.reject);
}catch(e){
this.reject(e);
}
}
处理 then 方法回调中的异常
then(successCallback, failCallback){
// 参数可选
successCallback = successCallback ? successCallback : value => value;
// 参数可选
failCallback = failCallback ? failCallback: reason => { throw reason };
let p2 = new MyPromise((resolve, reject) => {
if(this.status === FULFILLED){
try{
let result = successCallback(this.value);
resolvePromise(result, resolve, reject);
}catch(e){
reject(e);
}
}else if(this.status === REJECTED){
try{
let result = failCallback(this.reason);
resolvePromise(result, resolve, reject);
}catch (e) {
reject(e);
}
}else if(this.status === PENDING){
this.successCallbacks.push(() => {
try{
let result = successCallback(this.value);
resolvePromise(result, resolve, reject);
}catch (e) {
reject(e);
}
});
this.failCallbacks.push(() => {
try{
let result = failCallback(this.reason);
resolvePromise(result, resolve, reject);
}catch (e) {
reject(e);
}
});
}
});
return p2;
}
创建 catch 方法(直接调用then方法)
catch(failCallback){
return this.then(undefined, failCallback)
}
添加 Promise.resolve
- 处理 promise 实例,直接返回
- 处理 thenAbled对象(具有then方法的对象)
- 处理其它
static resolve(value){
if(value instanceof MyPromise){
return value;
}else if(Object.prototype.toString.call(value) === '[object Object]'
&& Object.prototype.toString.call(value.then) === '[object Function]'){
return new MyPromise(value.then);
} else {
return new MyPromise(resolve => resolve(value));
}
}
添加 finally 方法
- 在成功和失败后都执行
- 处理 finally 回调返回 promise
finally(callback){
const P = this.constructor;
// callback中如果返回的promise是rejected,返回的promise是rejected
// 如果返回的promise是fulfilled,返回的promise保持原来的
return this.then(
res => P.resolve(callback()).then(() => res, err => err),
err => P.resolve(callback()).then(() => {throw err}, err => err)
)
}
实现 all 方法
static all(arr){
return new MyPromise((resolve, reject) => {
let result = [];
function addResult(key, value){
result[key] = value;
if(result.length === arr.length){
resolve(result);
}
}
arr.forEach((value, index) => {
if(value instanceof MyPromise){
value.then(res => {
addResult(index, res);
}, err => {
reject(err);
})
}else{
addResult(index, value);
}
})
})
}
完整代码
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';
class MyPromise{
constructor(executor){
try{
executor(this.resolve, this.reject);
}catch(e){
this.reject(e);
}
}
status = PENDING;
value = '';
reason = '';
successCallbacks = [];
failCallbacks = [];
resolve = value => {
if(value instanceof MyPromise){
value.then(this.resolve, this.reject);
return;
}
if(this.status !== PENDING) return;
this.status = FULFILLED;
this.value = value;
while (this.successCallbacks.length){
this.successCallbacks.shift()();
}
}
reject = reason => {
if(this.status !== PENDING) return;
this.status = REJECTED;
this.reason = reason;
while (this.failCallbacks.length){
this.failCallbacks.shift()();
}
}
then(successCallback, failCallback){
// 参数可选
successCallback = successCallback ? successCallback : value => value;
// 参数可选
failCallback = failCallback ? failCallback: reason => { throw reason };
let p2 = new MyPromise((resolve, reject) => {
if(this.status === FULFILLED){
try{
let result = successCallback(this.value);
resolvePromise(result, resolve, reject);
}catch(e){
reject(e);
}
}else if(this.status === REJECTED){
try{
let result = failCallback(this.reason);
resolvePromise(result, resolve, reject);
}catch (e) {
reject(e);
}
}else if(this.status === PENDING){
this.successCallbacks.push(() => {
try{
let result = successCallback(this.value);
resolvePromise(result, resolve, reject);
}catch (e) {
reject(e);
}
});
this.failCallbacks.push(() => {
try{
let result = failCallback(this.reason);
resolvePromise(result, resolve, reject);
}catch (e) {
reject(e);
}
});
}
});
return p2;
}
catch(failCallback){
return this.then(undefined, failCallback)
}
finally(callback){
const P = this.constructor;
// callback中如果返回的promise是rejected,返回的promise是rejected
// 如果返回的promise是fulfilled,返回的promise保持原来的
return this.then(
res => P.resolve(callback()).then(() => res, err => err),
err => P.resolve(callback()).then(() => {throw err}, err => err)
)
}
static resolve(value){
if(value instanceof MyPromise){
return value;
}else if(Object.prototype.toString.call(value) === '[object Object]'
&& Object.prototype.toString.call(value.then) === '[object Function]'){
return new MyPromise(value.then);
} else {
return new MyPromise(resolve => resolve(value));
}
}
static all(arr){
return new MyPromise((resolve, reject) => {
let result = [];
function addResult(key, value){
result[key] = value;
if(result.length === arr.length){
resolve(result);
}
}
arr.forEach((value, index) => {
if(value instanceof MyPromise){
value.then(res => {
addResult(index, res);
}, err => {
reject(err);
})
}else{
addResult(index, value);
}
})
})
}
}
function resolvePromise(x, resolve, reject){
if(x instanceof MyPromise){
x.then(resolve, reject);
}else{
resolve(x);
}
}
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhgajkfe
系列文章
更多
同类精品
更多
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
怎样阻止微信小程序自动打开
PHP中文网 06-13 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01