目录
promsie接受一个函数作为参数,这个函数称作exe,exe包含 resolve和reject两个参数 是两个函数,内部的异步任务会放入对应的异步队列 等着then的执行
相当于收集依赖-〉触发通知-〉取出依赖执行
1. 构造函数mypromise
class mypromise {
constructor(exe) {
if(typeof exe !=='function'){
throw new Error('must accept function')
}
this._fulfilledqueues=[]
//成功回调函数队列
this._rejectedqueues=[]
//失败回调函数队列
try {
exe(this._resolve.bind(this),this._reject.bind(this))
} catch (err) {
this._reject(err)
}
}
_resolve(val) {
while(this._fulfilledqueues.length) {
const callback = this._fulfilledqueues.shift()
callback(val)
}
}
_reject(val) {
while(this._rejectedqueue.length){
const callback = this._rejectedqueue.shift()
callback(val)
}
}
}
1 将_resolve和_reject分别封装到函数里 然后放到settimeout里,防止exec是同步的
2 加入状态,then方法能被同一个promise调用多次
const pending = 'PENDING'
const fulfilled = 'FULFILLED'
const rejected = 'REJECTED'
class MyPromise {
constructor(executor) {
if (typeof executor !=='function') {
throw new Error(`MyPromise must accept a function as a parameter`)
}
this._status=pending
this._val=undefined
this._fulfilledQueues = [] // 成功回调函数队列
this._rejectedQueues = [] // 失败回调函数队列
try {
executor(this._resolve.bind(this), this._reject.bind(this))
} catch (err) {
this._reject(err)
}
}
_resolve(val) {
// 依次执行成功队列中的函数,并清空队列
let run=()=>{
if(this._status!==pending)return
this._status=fulfilled
this._val=val
while (this._fulfilledQueues.length) {
const callback = this._fulfilledQueues.shift()
callback(val)
}
}
setTimeout(run)
}
_reject(err) {
let run = ()=>{
if(this._status!==pending)return
this._status=reject
this._val=err
// 依次执行成功队列中的函数,并清空队列
while (this._rejectedQueues.length) {
const callback = this._rejectedQueues.shift()
callback(val)
}
}
setTimeout(run)
}
}
2. then 方法的实现
首先原本函数两个返回值
如果返回的是普通值 就直接处理
所以只有当当前状态还没决定时候再调用当前的onfulfill和onreject
then(onfulfilled,onrejected) {
const {_val,_status} =this
return new mypromise((onfulfillednext,onrejectednext)=>{
let fulfilled=val=>{
try {
if(!isfunction(onfulfilled) {
onfulfillednext(val)
} else {
let res = onfulfilled(val)
if(res instanceof mypromise) {
res.then(onfulfillednext,onrejectednext)
} else {
onfulfillednext(res)
}
}
} catch(err) {
onrejectednext(err)
}
}
let rejected = error=>{
try {
if(!isfunction(onrejected)) {
onrejectednext(error)
} else {
let res=onrejected(error)
if(res instanceof mypromise) {
res.then(onfulfillednext,onrejectednext)
} else {
onfulfillednext(res)
}
}
} catch(err) {
onrejectednext(err)
}
}
switch (_status) {
case pending:
this._fulfilledqueues.push(fulfilled)
this._rejectedqueues.push(rejected)
break;
case fulfilled:
fulfilled(_value)
break;
case rejected:
rejected(_value)
break;
}
})
}
3. 静态方法 resolve的实现
static resolve(value) {
if(value instanceOf mypromise)return value
return new mypromise((resolve)=>resolve(value))
}
4. 静态方法 reject实现
static reject(value) {
return new mypromise((resolve,reject)=>reject(value))
}
5. catch方法实现
catch方法是then方法的简化形式,是promise.then(undefined,onrejected)方法的别名
catch(onrejected) {
return this.then(undefined, onrejected)
}
允许在 `Promise` 的 `then` 或 `catch` 后插入一个回调
6. 模拟finally方法实现
Promise.prototype.myfinally=function(callback){
return this.then(
val=>{
return Promise.resolve(callback()).then(()=>val)
},
reason=>{
return Promise.resolve(callback()).then(()=>{throw reason})
}
)
}
测试:
Promise.resolve(1).myfinally(()=>console.log('aa')).then((re)=>console.log(re))
Promise.reject('no').myfinally(()=>console.log('aa')).catch((err)=>console.log(err))