- promise 就是一个类,在执行这个类的时候,需要传递一个执行器,执行器会立即执行
- promise 中有3种状态,分别为成功(fulfilled),失败(rejected)和进行中(pending) pedding->fulfilled pedding->rejected
- resolve 和reject函数是来更新状态
- resolve:fulfilled reject: rejected
- then方法是判断状态,如果状态是成功则调用成功回调函数,如果状态是失败则调用失败回调函数。then方法是被定义在原型对象中
- then成功回调有一个参数,表示成功之后的值,then失败回调有一个参数,表示失败后的原因
- then方法是可以被调用的,后面的then方法的回调函数拿到值的是上一个then方法的回调函数返回值
思考Promise写法注意点
- 写主体逻辑代码,第一步先写出一个类,之后再一步一步构造
- 之后考虑异步调用resolve,传入的是异步代码。所以将成功失败函数存起来,判断是否需要异步再次调用
- 当有多个then调用的时候,我们就需要考虑使用数组
- 当then,有多层嵌套的时候。需要处理then的链式调用,如何把then的返回值返回到下一个then中,需要返回promisee对象.
- 所以需要封装promise,实现链式调用
- 如果出现循环调用promise的时候,
- 错误处理,会在构造器中使用try.catch,在then成功回调函数里面也使用try.catch
- Promise.all() 写静态文件函数all()来处理
- Promise.resolve() 直接传参数,进行返回判断是promise对象还是非promise对象。是对象的化,直接返回,不是的化,生产一个对象,包裹返回
- Primise.finally() 不管promise执行是否成功还是失败,finally()依然会执行一次。可以通过then的方法获取到这个promise的最终结果
- finally()不是类的方法,是原型对象上的方法。
- Primise.catch() 是原型对象的方法。如果then没有打印错误,catch()里需要捕获
const PENDING = 'pending';
const FULFILLED = 'filfull ed';
const REJECTED = 'rejected';
class MyPromise {
constructor(executor){
try{
executor(this.resolve,this.reject)
}catch(e){
this.reject(e)
}
};
status = PENDING;
value = undefined;
reason = undefined;
successCallback = []
failCallback = []
resolve = value =>{
if(this.status !== PENDING) return
this.status = FULFILLED;
this.value = value
while(this.successCallback.length) this.successCallback.shift()()
};
reject = err =>{
if(this.status !== PENDING) return
this.status = REJECTED;
this.reason = err
while(this.failCallback.length) this.failCallback.shift()()
}
then(successCallback,failCallback){
successCallback= successCallback ? successCallback : value=>value;
failCallback= failCallback ? failCallback : reson=>{ throw(reson)};
let promise2 = new MyPromise((resolve,reject)=>{
if(this.status === FULFILLED){
setTimeout(()=>{
try{
let x = successCallback(this.value)
resolvePrimise(promise2 ,x,resolve,reject)
}catch(e){
reject(e)
}
},0)
}else if(this.status === REJECTED){
setTimeout(()=>{
try{
let x = failCallback(this.reason)
resolvePrimise(promise2 ,x,resolve,reject)
}catch(e){
reject(e)
}
},0)
}else{
this.successCallback.push(()=>{
setTimeout(()=>{
try{
let x = successCallback(this.value)
resolvePrimise(promise2 ,x,resolve,reject)
}catch(e){
reject(e)
}
},0)
})
this.failCallback.push(()=>{
setTimeout(()=>{
try{
let x = failCallback(this.reason)
resolvePrimise(promise2 ,x,resolve,reject)
}catch(e){
reject(e)
}
},0)
})
}
})
return promise2
}
finaally(callback){
return this.then(value =>{
return MyPromise.resolve(callback()).then(()=> value)
},reject=>{
return MyPromise.resolve(callback()).then(()=> {throw reject})
})
}
catch(failCallback){
return this.then(undefined,failCallback)
}
static all(array){
let result = [];
let index = 0
return new MyPromise((resolve,reject)=>{
function addData(key,value){
result[key] = value;
index++
if(index === array.length){
resolve(result)
}
}
for(let i= 0;i<array.length;i++){
let current = array[i];
if(current instanceof MyPromise){
current.then(value =>addData(i,value) ,reson =>{
reject(reson)
})
}else{
addData(i,array[i]);
}
}
})
}
static resolve(val){
if(val instanceof MyPromise) val
return new MyPromise(resolve=>resolve(val))
}
}
function resolvePrimise(promise2,x,resolve,reject){
* *if(promise2 === x){
return reject(new TypeError('Chaining cycle detected for promise #<Promise>'))
}
if(x instanceof MyPromise){
x.then(resolve,reject)
}else{
resolve(x)
}
}
这是主体代码 第一步,都是基于第一步进行改编。结合思考Promise写法注意点
const PENDING = 'peding'
const REJECTED = 'rejected'
const FILFULLED = 'filfulled'
class MyPromise{
constructor(executor){
executor(this.resolve,this.reject)
}
status = PENDING
value = undefined
filed = undefined
resolve = value =>{
if(this.status !== PENDING) return
this.status = FILFULLED
this.value = value
}
reject = filed =>{
if(this.status !== PENDING) return
this.status = REJECTED
this.filed = filed
}
then(successCallback,failCallback){
if(this.status == FILFULLED){
successCallback(this.value)
}else if(this.status == REJECTED){
failCallback(this.filed)
}
}
}
let b= new MyPromise((resolve,reject)=>{
reject('shibao')
})
b.then(res=>{
console.log(res)
},err=>{
console.log(err)
})
以下是代码测试区域,仅供参考,可以自己实现测试方法
let primise = new MyPromise((resolve,reject)=>{
setTimeout(()=>{
resolve('成功1')
},2000)
})
let primise1 = new MyPromise((resolve,reject)=>{
reject('p2 失败')
})
primise1.then(value=>console.log(value))
.catch(reasonn=> console.log(reasonn))