《Promise学习笔记》- 4Promise自定义封装之thencatch的封装
Posted 仙贝wang
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《Promise学习笔记》- 4Promise自定义封装之thencatch的封装相关的知识,希望对你有一定的参考价值。
定义then方法
前面只是对then方法简单的定义,另外还需要注意then方法的两大特性:
-
同时指定多个回调都会被调用;
实现方法:在实例对象自身身上初始化一个空数组callbacks,当状态为pending时,将多个回调以一组对象的形式push进数组中用于被执行。
-
then方法的链式调用,因为then方法能够返回一个promise对象。
// 定义then方法
then(onResolved,onRejected){
// 保存this指向
const self = this;
// then返回结果仍然是一个Promise
return new Promise((resolve,reject)=>{
// 封装回调函数(是代码简洁)
function callback(type){
try {
let res = type(self.PromiseResult);
if(res instanceof Promise){
res.then(v => {
resolve(v);
},r => {
reject(r);
})
}else{
resolve(res);
}
} catch (e) {
reject(e)
}
}
// 状态为成功时的回调
if(this.PromiseState === \'fulfilled\'){
callback(onResolved);
};
// 状态为失败时的回调
if(this.PromiseState === \'rejected\'){
callback(onRejected);
}
// 状态为pending时,将多个回调压入到callbacks数组中
if(this.PromiseState === \'pending\'){
this.callbacks.push({
onResolved:function(){
callback(onResolved);
},
onRejected:function(){
callback(onRejected);
}
})
}
})
}
定义catch方法
定义好then方法之后,catch方法的定义就会简单很多!我们知道,可以将catch方法看作是then(undefined,onRejected)的语法糖,所以在定义时可以直接调用实例身上的then方法!
// 定义catch方法
catch(onRejected){
return this.then(undefined,onRejected)
}
自定义封装终极版
综合了一下前面的定义,下面是完整的自定义代码!主要实现了构造器函数和Promise.resolve()、Promise.reject()、Promise.all()、Promise.race()、Promise.prototype.then()、Promise.prototype.catch()这六个方法!大家可以试着敲敲看,如有错误还请指正,谢谢!
class Promise{
// 定义构造器函数
constructor(executor){
// 初始化状态和状态值
this.PromiseState = \'pending\';
this.PromiseResult = null;
// 保存this,由于函数内部this默认指向window
const self = this;
// 定义一个空数组,用于保存回调
this.callbacks = [];
// 定义resolve函数
function resolve(data){
// 保证状态只能修改一次
if(self.PromiseState !== \'pending\') return;
// 状态变为成功
self.PromiseState = \'fulfilled\';
// 状态值变为传入的参数值
self.PromiseResult = data;
// 异步任务时成功的回调,保证多个then的同时调用
self.callbacks.forEach(item => {
item.onResolved(data);
});
};
// 定义reject函数
function reject(data){
if(self.PromiseState !== \'pending\') return;
self.PromiseState = \'rejected\';
self.PromiseResult = data;
// 异步任务时失败的回调
self.callbacks.forEach(item => {
item.onRejected(data);
});
};
// 当抛出异常时,使用try...catch捕获
try{
executor(resolve,reject);
}catch(e){
// 直接调用reject函数将对象状态变为失败,此时e为失败的状态值
reject(e);
}
}
// 定义then方法
then(onResolved,onRejected){
// 保存this指向
const self = this;
// then返回结果仍然是一个Promise
return new Promise((resolve,reject)=>{
// 封装回调函数
function callback(type){
try {
let res = type(self.PromiseResult);
if(res instanceof Promise){
res.then(v => {
resolve(v);
},r => {
reject(r);
})
}else{
resolve(res);
}
} catch (e) {
reject(e)
}
}
// 状态为成功时的回调
if(this.PromiseState === \'fulfilled\'){
callback(onResolved);
};
// 状态为失败时的回调
if(this.PromiseState === \'rejected\'){
callback(onRejected);
}
// 状态为pending时,将多个回调压入到callbacks数组中
if(this.PromiseState === \'pending\'){
this.callbacks.push({
onResolved:function(){
callback(onResolved);
},
onRejected:function(){
callback(onRejected);
}
})
}
})
}
// 定义catch方法
catch(onRejected){
return this.then(undefined,onRejected)
}
// 定义resolve方法
static resolve(value){
return new Promise((resolve,reject)=>{
if(value instanceof Promise){
value.then(v => {
resolve(v);
},r => {
reject(r);
})
}else{
resolve(value);
}
})
}
// 定义reject方法
static reject(reason){
return new Promise((resolve,reject)=>{
reject(reason)
})
}
// 定义all()方法
static all(promises){
return new Promise((resolve,reject)=>{
// 记录数组中成功状态Promise的个数
let count = 0;
// 保存成功的状态值
let arr = [];
for(let i=0;i<promises.length;i++){
promises[i].then(v => {
count++;
arr[i]=v;
// 如果成功的个数等于数组长度,则说明每个都成功
if(count === promises.length){
resolve(arr);
}
},r => {
reject(r);
})
};
})
}
// 定义race()方法
static race(promises){
return new Promise((resolve,reject)=>{
for(let i=0;i<promises.length;i++){
promises[i].then(v => {
resolve(v);
},r => {
reject(r);
})
}
})
}
}
以上是关于《Promise学习笔记》- 4Promise自定义封装之thencatch的封装的主要内容,如果未能解决你的问题,请参考以下文章
Promise原理讲解 async+await应用(异步回调解决方案)