- 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){
//因为在类里面所以需要this.才能访问
try{
executor(this.resolve,this.reject)
}catch(e){
this.reject(e)
}
};
//Promise 状态
status = PENDING;
// //成功之后的值
value = undefined;
//失败之后的原因
reason = undefined;
//成功的回调
successCallback = []
//失败的回调
failCallback = []
resolve = value =>{
//如果状态不是等待,就阻止程序想下执行
if(this.status !== PENDING) return
//将状态更改为成功
this.status = FULFILLED;
//保存成功的值
this.value = value
//判断成功回调是否存在 shift()删除其中的第一个值,获取到,并且返回剩下的数组
while(this.successCallback.length) this.successCallback.shift()()
};
reject = err =>{
//如果状态不是等待,就阻止程序想下执行
if(this.status !== PENDING) return
//将状态更改为失败
this.status = REJECTED;
//保存失败的原因
this.reason = err
//判断失败回调是否存在 shift()删除其中的第一个值,获取到,并且返回剩下的数组
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){
//此处是不能获取到promise2的,只有new MyPromise执行之后才会获取到。我们现在是在new MyPromise过程中
//(所以将promise2变成异步代码使用setTimeout让其改变成异步代码,让所有代码执行完成,promise2就有了,然后我们去执行函数内部的代码)
setTimeout(()=>{
try{
//判断X的值是普通函数还是Promise对象
//如果是普通值,直接调用resolve
//如果是primise对象,查看promise对象返回的结果
//再根据promise对象返回的结果,决定调用resolve还是reject
let x = successCallback(this.value)
//判断 promise2 和X 是否相等,如果相等,就等于返回了自己
resolvePrimise(promise2 ,x,resolve,reject)
}catch(e){
reject(e)
}
},0)
}else if(this.status === REJECTED){
//此处是不能获取到promise2的,只有new MyPromise执行之后才会获取到。我们现在是在new MyPromise过程中
//(所以将promise2变成异步代码使用setTimeout让其改变成异步代码,让所有代码执行完成,promise2就有了,然后我们去执行函数内部的代码)
setTimeout(()=>{
try{
//判断X的值是普通函数还是Promise对象
//如果是普通值,直接调用resolve
//如果是primise对象,查看promise对象返回的结果
//再根据promise对象返回的结果,决定调用resolve还是reject
let x = failCallback(this.reason)
// 判断 promise2 和X 是否相等,如果相等,就等于返回了自己
resolvePrimise(promise2 ,x,resolve,reject)
}catch(e){
reject(e)
}
},0)
}else{
//等待状态
//将成功回调和失败回调存起来
this.successCallback.push(()=>{
setTimeout(()=>{
try{
//判断X的值是普通函数还是Promise对象
//如果是普通值,直接调用resolve
//如果是primise对象,查看promise对象返回的结果
//再根据promise对象返回的结果,决定调用resolve还是reject
let x = successCallback(this.value)
// 判断 promise2 和X 是否相等,如果相等,就等于返回了自己
resolvePrimise(promise2 ,x,resolve,reject)
}catch(e){
reject(e)
}
},0)
})
this.failCallback.push(()=>{
setTimeout(()=>{
try{
//判断X的值是普通函数还是Promise对象
//如果是普通值,直接调用resolve
//如果是primise对象,查看promise对象返回的结果
//再根据promise对象返回的结果,决定调用resolve还是reject
let x = failCallback(this.reason)
// 判断 promise2 和X 是否相等,如果相等,就等于返回了自己
resolvePrimise(promise2 ,x,resolve,reject)
}catch(e){
reject(e)
}
},0)
})
}
})
return promise2
}
finaally(callback){
//通过调用then的方法,我们可以得到成功还是失败。无论什么情况都可以调用
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)
}
//声明all是一个静态方法
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){
//promise对象
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))
}
}
//判断是普通值还是Mypromisee
function resolvePrimise(promise2,x,resolve,reject){
* *if(promise2 === x){
// 使用return,阻止下面代码执行了
return reject(new TypeError('Chaining cycle detected for promise #<Promise>'))
}
//x是否属于Mypromisee类下面的实例,
if(x instanceof MyPromise){
//primose
//x.then(value=>resolve(value),err => reject(err))
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)=>{
// resolve('成功')
reject('shibao')
})
b.then(res=>{
console.log(res)
},err=>{
console.log(err)
})
复制代码
以下是代码测试区域,仅供参考,可以自己实现测试方法
let primise = new MyPromise((resolve,reject)=>{
// throw new Error('executor Error')
// resolve('成功')
setTimeout(()=>{
resolve('成功1')
},2000)
// resolve('成功')
// reject('失败')
})
let primise1 = new MyPromise((resolve,reject)=>{
// resolve('p3 成功')
// setTimeout(()=>{
// resolve('成功1')
// },2000)
reject('p2 失败')
})
// a.then((resolve)=>{
// console.log(resolve)
// //throw new Error('then Error')
// return 'aaa';
// },err=>{
// console.log(err)
// return 10000
// }).then((resolve)=>{
// console.log(resolve)
// })
// primise1.finaally(()=>{
// console.log('finaally')
// return primise
// }).then(value=>{
// console.log(value)
// },resone=>{
// console.log(resone)
// })
primise1.then(value=>console.log(value))
.catch(reasonn=> console.log(reasonn))
// primise.then().then().then().then(value=>console.log(value),err=>{
// console.log(err)
// })
// MyPromise.all(['a','b',primise,primise1,'c']).then(res=>console.log(res),rej=>console.log(rej))
// MyPromise.resolve(100).then(value=>console.log(value))
// MyPromise.resolve(primise).then(value=>console.log(value))
//此时promise被循环调用
// var cc = new Promise((res,rej)=>{
// res(100)
// })
// let p = cc.then((res)=>{
// console.log(res)
// return p
// })
// p.then(()=>{},(err)=>{
// console.log(err)
// })
复制代码
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END