- 第一版
<!DOCTYPE html>
<div>手写promise</div>
<script>
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';
class MyPromise{
constructor(executor){
executor(this.resolve, this.reject)
}
state = PENDING
res = null
err = null
resolve = (r) => {
if(this.state === PENDING){
this.state = FULFILLED
this.res = r
}
}
reject = (e) => {
if (this.state === PENDING) {
this.state = REJECTED
this.err = e
}
}
then(onFulFilled,onRejected){
if(this.state === FULFILLED){
onFulFilled(this.res)
} else if(this.state === REJECTED){
onRejected(this.err)
}
}
}
var prmosise = new MyPromise((resolve,reject)=>{
resolve('SUCCESS')
reject('ERROR')
})
prmosise.then(res=>{
console.log('resolve',res)
},err=>{
console.log('reject',err)
})
</script>
var prmosise = new MyPromise((resolve,reject)=>{
setTimeout(res=>{
resolve('SUCCESS')// 此时加异步无法执行 因为then是立即执行函数 会导致主线程走完在调取setTimeout,此时的state是pending ,resolve无法返回值,所以resolve里面要执行缓存的reaolveCallback函数
},2000)
})
prmosise.then(res=>{
console.log('resolve',res)
},err=>{
console.log('reject',err)
})
无输出
此时加异步无法执行 因为then是立即执行函数 会导致主线程走完在调取setTimeout,此时的state是pending ,resolve无法返回值,所以resolve里面要执行缓存的reaolveCallback函数
- 第二版,<支持异步逻辑>
<script>
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';
class MyPromise{
constructor(executor){
executor(this.resolve, this.reject)
}
state = PENDING
res = null
err = null
onFulFilledCallback = null
onRejectedCallback = null
resolve = (r) => {
if(this.state === PENDING){
this.state = FULFILLED
this.res = r
this.onFulFilledCallback && this.onFulFilledCallback(r)
}
}
reject = (e) => {
if (this.state === PENDING) {
this.state = REJECTED
this.err = e
this.onRejectedCallback && this.onRejectedCallback(e)
}
}
then(onFulFilled,onRejected){
if(this.state === FULFILLED){
onFulFilled(this.res)
} else if(this.state === REJECTED){
onRejected(this.err)
} else if (this.state === PENDING){ // 缓存resolve和reject方法,为了异步使用
this.onFulFilledCallback = onFulFilled
this.onRejectedCallback = onRejected
}
}
}
var prmosise = new MyPromise((resolve,reject)=>{
setTimeout(res=>{
resolve('SUCCESS')
},2000)
})
prmosise.then(res=>{
console.log('resolve',res) // 输出resolve SUCCESS
},err=>{
console.log('reject',err)
})
</script>
使用第二版的执行以下逻辑
var promise = new MyPromise((resolve,reject)=>{
setTimeout(res=>{
resolve('SUCCESS')
},2000)
})
promise.then(value => {
console.log(1)
console.log('resolve', value)
})
promise.then(value => {
console.log(2)
console.log('resolve', value)
})
promise.then(value => {
console.log(3)
console.log('resolve', value)
})
输出
3
promise.html:64 resolve SUCCESS
为什么 1,2丢了呢?因为最后一次的then方法会把前两次的覆盖掉
如何实现都出来呢?那就需要把之前的两次的方法给缓存起来
- 第三版 <实现then方法多次条用添加多个处理函数>
<script>
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';
class MyPromise{
constructor(executor){
executor(this.resolve, this.reject)
}
state = PENDING
res = null
err = null
onFulFilledCallbacks = []
onRejectedCallbacks = []
resolve = (r) => {
if(this.state === PENDING){
this.state = FULFILLED
this.res = r
this.onFulFilledCallbacks.forEach(itemFun => {
itemFun && itemFun(r)
})
}
}
reject = (e) => {
if (this.state === PENDING) {
this.state = REJECTED
this.err = e
this.onRejectedCallbacks.forEach(itemFun => {
itemFun && itemFun(e)
});
}
}
then(onFulFilled,onRejected){
if(this.state === FULFILLED){
onFulFilled(this.res)
} else if(this.state === REJECTED){
onRejected(this.err)
} else if (this.state === PENDING){ // 缓存resolve和reject方法,为了异步使用
this.onFulFilledCallbacks.push(onFulFilled)
this.onRejectedCallbacks.push(onRejected)
}
}
}
var promise = new MyPromise((resolve,reject)=>{
setTimeout(res=>{
resolve('SUCCESS')
},2000)
})
promise.then(value => {
console.log(1)
console.log('resolve', value)
})
promise.then(value => {
console.log(2)
console.log('resolve', value)
})
promise.then(value => {
console.log(3)
console.log('resolve', value)
})
</script>
使用第三版无法处理then链式调用的问题
如下
var promise = new MyPromise((resolve,reject)=>{
resolve('success')
}).then(value => {
return new MyPromise((resolve, reject) => {
resolve('1')
})
}).then(value => {
return new MyPromise((resolve, reject) => {
resolve('2')
})
}).then(value => {
return new MyPromise((resolve, reject) => {
resolve('3')
})
})
因为之前写的then都是一个立即执行函数 并不是又返回一个promise
接下来我们来实现它
- 第四版 <实现then的链式调用>
需要知道链式调用的原理 :
即then返回一个promise
<script>
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';
class MyPromise{
constructor(executor){
executor(this.resolve, this.reject)
}
state = PENDING
res = null
err = null
onFulFilledCallbacks = []
onRejectedCallbacks = []
resolve = (r) => {
if(this.state === PENDING){
this.state = FULFILLED
this.res = r
this.onFulFilledCallbacks.forEach(itemFun => {
itemFun && itemFun(r)
})
}
}
reject = (e) => {
if (this.state === PENDING) {
this.state = REJECTED
this.err = e
this.onRejectedCallbacks.forEach(itemFun => {
itemFun && itemFun(e)
});
}
}
then(onFulFilled,onRejected){
// if(this.state === FULFILLED){
// onFulFilled(this.res)
// } else if(this.state === REJECTED){
// onRejected(this.err)
// } else if (this.state === PENDING){ // 缓存resolve和reject方法,为了异步使用
// this.onFulFilledCallbacks.push(onFulFilled)
// this.onRejectedCallbacks.push(onRejected)
// }
return new MyPromise((resolve, reject) => {
debugger
if(this.state === FULFILLED){
const x = onFulFilled(this.res)
resolvePrmiseFun(x, resolve, reject) // 集中处理
} else if(this.state === REJECTED){
onRejected(this.err)
} else if (this.state === PENDING) {
this.onFulFilledCallbacks.push(onFulFilled)
this.onRejectedCallbacks.push(onRejected)
}
})
}
}
function resolvePrmiseFun(x, resolve, reject){
// 判断x是不是 MyPromise 实例对象
if(x instanceof MyPromise){
x.then(resolve, reject)
} else {
resolve(x)
}
}
var promise = new MyPromise((resolve,reject)=>{
resolve('success')
}).then(value => {
return new MyPromise((resolve, reject) => {
console.log('resolve',value)
resolve('1')
})
}).then(value => {
return new MyPromise((resolve, reject) => {
console.log('resolve', value)
resolve('2')
})
}).then(value => {
return new MyPromise((resolve, reject) => {
console.log('resolve', value)
resolve('3')
})
})
</script>