promise简写版
- Promise是个类,在执行这个类的时候,需要传递一个执行器进去,执行器会立即执行
- Promise有三个状态,分别为成功fullfilled、失败rejected,等待pending,一旦状态变化就不可更改
- resolve和reject函数是用来更改状态的
- then方法内做的事情就是判断状态,如果状态是成功,调用成功的函数,如果是失败,调用失败的函数
- then成功回调有一个参数,表示成功之后的值,失败的时候传失败的原因
- 测试用例
new Promise((resolve,reject)=>{
resolve('成功')
// reject('失败')
})
- 代码实现
class MyPromise{
static PENDING = 'pending'
static FULLFILLED = 'fullfilled'
static REJECTED = 'rejected'
constructor(executor){
this.status = MyPromise.PENDING
this.value = undefined
this.reason = undefined
executor(this.resolve,this.reject)
}
resolve = (value)=>{
if(this.status!==MyPromise.PENDING) return
this.status!==MyPromise.FULLFILLED
this.value = value
}
reject = (reason)=>{
if(this.status!==MyPromise.PENDING) return
this.status!==MyPromise.REJECTED
this.reason = reason
}
then(successCallback,failCallback) {
if(this.status===MyPromise.FULLFILLED){
successCallback(this.value)
}else if(this.status===MyPromise.REJECTED){
failCallback(this.reason)
}
}
}
第二版,支持异步和then方法多次调用添加多个处理函数
- 测试函数
let promise = new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve('成功')
},2000)
// reject('失败')
})
promise.then(value=>{
console.log(value)
},reason=>{
console.log(1)
console.log(reason)
})
promise.then(value=>{
console.log(2)
console.log(value)
},reason=>{
console.log(reason)
})
- 代码实现
class MyPromise{
static PENDING = 'pending'
static FULLFILLED = 'fullfilled'
static REJECTED = 'rejected'
constructor(executor){
this.status = MyPromise.PENDING
this.value = undefined
this.reason = undefined
this.successCallback = []
this.failCallback = []
executor(this.resolve,this.reject)
}
resolve = (value)=>{
if(this.status!==MyPromise.PENDING) return
this.status!==MyPromise.FULLFILLED
this.value = value
while(this.successCallback.length){
let cb = this.successCallback.shift()
cb(this.value)
}
}
reject = (reason)=>{
if(this.status!==MyPromise.PENDING) return
this.status!==MyPromise.REJECTED
this.reason = reason
while(this.failCallback.length){
let cb = this.failCallback.shift()
cb(this.reason)
}
}
then(successCallback,failCallback) {
if(this.status===MyPromise.FULLFILLED){
successCallback(this.value)
}else if(this.status===MyPromise.REJECTED){
failCallback(this.reason)
}else {
successCallback && this.successCallbacks.push(successCallback)
failCallback && this.failCallback.push(failCallback)
}
}
}
第三版 实现then方法的链式调用
- 实现then方法的链式调用,需要返回一个promise
- 实现then方法值的传递:把上一个回调函数的return返回值,通过resolve传给下一个then方法
- return的值可以是普通值,也可以是一个promise对象
- 测试用例
let promise = new Promise((resolve,reject)=>{
resolve('成功')
// reject('失败')
})
promise.then(value=>{
console.log(value)
// then方法return的值是下一个then方法接收到的value参数
return 100
}).then(value=>{
console.log(value)
})
// 支持.then return的值是promise的例子
function other(){
return new Promise((resolve,reject)=>{
resolve('other')
})
}
promise.then(value=>{
console.log(value)
// then方法return的值是下一个then方法接收到的value参数
return other()
}).then(value=>{
console.log(value)
})
- 代码实现
class MyPromise{
static PENDING = 'pending'
static FULLFILLED = 'fullfilled'
static REJECTED = 'rejected'
constructor(executor){
this.status = MyPromise.PENDING
this.value = undefined
this.reason = undefined
this.successCallback = []
this.failCallback = []
executor(this.resolve,this.reject)
}
resolve = (value)=>{
if(this.status!==MyPromise.PENDING) return
this.status!==MyPromise.FULLFILLED
this.value = value
while(this.successCallback.length){
let cb = this.successCallback.shift()
cb(this.value)
}
}
reject = (reason)=>{
if(this.status!==MyPromise.PENDING) return
this.status!==MyPromise.REJECTED
this.reason = reason
while(this.failCallback.length){
let cb = this.failCallback.shift()
cb(this.reason)
}
}
then(successCallback,failCallback) {
let promise2 = new MyPromise((resolve,reject)=>{
if(this.status===MyPromise.FULLFILLED){
let x = successCallback(this.value)
// x是then成功回调函数的返回值,然后传给下一个then函数调用
// 判断x的值是普通值还是promise对象
// 如果是普通值,直接调用resolve
// 如果是promise对象,查看promise对象返回的结果
// 再根据promise对象返回的结果,决定调用resolve还是reject
// 由于这段判断成功失败还是pending都需要调用,则把它封装成函数
resolvePromise(x,resolve,reject)
}else if(this.status===MyPromise.REJECTED){
failCallback(this.reason)
}else {
successCallback && this.successCallbacks.push(successCallback)
failCallback && this.failCallback.push(failCallback)
}
})
return promise2
}
}
function resolvePromise(x, resolve, reject){
if(x instanceof MyPromise){
// promise函数
// 获取promise结果
x.then(resolve,reject)
}else {
// 普通值
resolve(x)
}
}
第四版 实现then方法链式调用识别Promise对象自返回
注意事项: 1. 在then方法的回调函数中,不能return当前promise.then方法的返回的promise对象,要不会产生循环调用
- 测试用例
let promise = new Promise((resolve,reject)=>{
resolve(100)
// reject('失败')
})
// !!!循环调用的例子
let p1 = promise.then(function(value){
console.log(value)
return p1
})
// 上边的报错要在下边的catch方法中捕获到
p1.then(()=>{
},err=>{
console.log(err) //这里打印报错
})
- 代码实现
class MyPromise{
static PENDING = 'pending'
static FULLFILLED = 'fullfilled'
static REJECTED = 'rejected'
constructor(executor){
this.status = MyPromise.PENDING
this.value = undefined
this.reason = undefined
this.successCallback = []
this.failCallback = []
executor(this.resolve,this.reject)
}
resolve = (value)=>{
if(this.status!==MyPromise.PENDING) return
this.status!==MyPromise.FULLFILLED
this.value = value
while(this.successCallback.length){
let cb = this.successCallback.shift()
cb(this.value)
}
}
reject = (reason)=>{
if(this.status!==MyPromise.PENDING) return
this.status!==MyPromise.REJECTED
this.reason = reason
while(this.failCallback.length){
let cb = this.failCallback.shift()
cb(this.reason)
}
}
then(successCallback,failCallback) {
let promise2 = new MyPromise((resolve,reject)=>{
if(this.status===MyPromise.FULLFILLED){
setTimeout(()=>{
// 这里如果x===promise2就代表返回了自己,需要调用reject抛出错误
let x = successCallback(this.value)
// 这里增加一个参数promise2
// 这里想要获取到promise2,需要变成异步代码才能获取到
resolvePromise(promise2,x,resolve,reject)
},0)
}else if(this.status===MyPromise.REJECTED){
failCallback(this.reason)
}else {
successCallback && this.successCallbacks.push(successCallback)
failCallback && this.failCallback.push(failCallback)
}
})
return promise2
}
}
function resolvePromise(promise2, x, resolve, reject){
if(promise2 === x){
return reject(new TypeError('Chaining cycle detected for promise #<Promise>'))
}
if(x instanceof MyPromise){
// promise函数
// 获取promise结果
x.then(resolve,reject)
}else {
// 普通值
resolve(x)
}
}
第五版 捕获错误及链式调用其它代码补充
- 捕获错误及链式调用其它代码补充
- 捕获执行器和then回调函数里的报错
class MyPromise{
static PENDING = 'pending'
static FULLFILLED = 'fullfilled'
static REJECTED = 'rejected'
constructor(executor){
try {
this.status = MyPromise.PENDING
this.value = undefined
this.reason = undefined
this.successCallback = []
this.failCallback = []
executor(this.resolve,this.reject)
}catch(e){
this.reject(e)
}
}
resolve = (value)=>{
if(this.status!==MyPromise.PENDING) return
this.status!==MyPromise.FULLFILLED
this.value = value
while(this.successCallback.length){
// 下边then方法里this.successCallbacks.push函数的时候传了值,这里不用传了
this.successCallback.shift()()
}
}
reject = (reason)=>{
if(this.status!==MyPromise.PENDING) return
this.status!==MyPromise.REJECTED
this.reason = reason
while(this.failCallback.length){
this.failCallback.shift()()
}
}
then(successCallback,failCallback) {
let promise2 = new MyPromise((resolve,reject)=>{
if(this.status===MyPromise.FULLFILLED){
setTimeout(()=>{
try{
let x = successCallback(this.value)
resolvePromise(promise2,x,resolve,reject)
}catch(e){
reject(e)
}
},0)
}else if(this.status===MyPromise.REJECTED){
setTimeout(()=>{
try{
let x = failCallback(this.reason)
resolvePromise(promise2,x,resolve,reject)
}catch(e){
reject(e)
}
},0)
}else {
successCallback && this.successCallbacks.push(()=>{
setTimeout(()=>{
try{
let x = successCallback(this.value)
resolvePromise(promise2,x,resolve,reject)
}catch(e){
reject(e)
}
},0)
})
failCallback && this.failCallback.push(()=>{
setTimeout(()=>{
try{
let x = failCallback(this.reason)
resolvePromise(promise2,x,resolve,reject)
}catch(e){
reject(e)
}
},0)
})
}
})
return promise2
}
}
第六版 将then方法的参数变成可选参数
- 测试用例
let promise = new Promise((resolve,reject)=>{
resolve(100)
})
promise
.then()
.then()
.then(value=>console.log(value))
// then方法什么都不传,等同于.then(value=>value),所以我们需要做的就是补充一下这个回调函数
promise
.then(value=>value)
.then(value=>value)
.then(value=>console.log(value))
- 代码实现
class MyPromise{
static PENDING = 'pending'
static FULLFILLED = 'fullfilled'
static REJECTED = 'rejected'
constructor(executor){
try {
this.status = MyPromise.PENDING
this.value = undefined
this.reason = undefined
this.successCallback = []
this.failCallback = []
executor(this.resolve,this.reject)
}catch(e){
this.reject(e)
}
}
// ......
then(successCallback,failCallback) {
successCallback = successCallback?successCallback:value=>value
failCallback = failCallback?failCallback:reason=>{throw reason}
// ...
}
}
第七版 finally和catch方法
class MyPromise{
static PENDING = 'pending'
static FULLFILLED = 'fullfilled'
static REJECTED = 'rejected'
constructor(executor){
try {
this.status = MyPromise.PENDING
this.value = undefined
this.reason = undefined
this.successCallback = []
this.failCallback = []
executor(this.resolve,this.reject)
}catch(e){
this.reject(e)
}
}
// ......
finally(cb){
return this.then(value=>{
// 兼容cb()是异步的轻举昂
return MyPromise.resolve(value(cb())).then(()=>value)
},reason=>{
return MyPromise.resolve(value(cb())).then(()=>{throw reason})
})
}
catch(failCallback){
return this.then(undefined,failCallback)
}
}
扩展
promise.all方法的实现,解决异步并发
- promise.all方法的实现,解决异步并发
- 接收的参数是一个数组,包括普通值和promise,
- 返回的值也是promise对象,
- 数组需要按照传入的顺序返回
- 静态方法
- 测试用例
function p1(){
return new Promise((resolve,reject)=>{
setTimeout(function(){
resolve('p1')
},2000)
})
}
function p2(){
return new Promise((resolve,reject)=>{
resolve('p2')
})
}
Promise.all(['a','b',p1(),p2(),'c']).then(function(result){
// result=>['a','b','p1','p2','c']
})
代码实现
class MyPromise{
static PENDING = 'pending'
static FULLFILLED = 'fullfilled'
static REJECTED = 'rejected'
constructor(executor){
try {
this.status = MyPromise.PENDING
this.value = undefined
this.reason = undefined
this.successCallback = []
this.failCallback = []
executor(this.resolve,this.reject)
}catch(e){
this.reject(e)
}
}
// ......
static all(arr){
let result = []
let index = 0
return new MyPromise((resolve,reject)=>{
function addData(key,value){
result[key] = value
index++
if(index === arr.length){
resolve(result)
}
}
for(let i = 0; i<arr.legnth; i++){
if(arr[i] instanceof MyPromise){
arr[i].then(value=>addData(i,value),reason=>reject(reason))
}else{
addData(i,arr[i])
}
}
})
}
}
Promise.resolve方法的实现,将resolve的值转为promise
class MyPromise{
static PENDING = 'pending'
static FULLFILLED = 'fullfilled'
static REJECTED = 'rejected'
constructor(executor){
try {
this.status = MyPromise.PENDING
this.value = undefined
this.reason = undefined
this.successCallback = []
this.failCallback = []
executor(this.resolve,this.reject)
}catch(e){
this.reject(e)
}
}
// ......
static resolve(value){
if(value instanceof MyPromise) return
return new MyPromise(resolve=>resolve(value))
}
}