IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> Typescript实现Promise[then|catch|finally|resolve|reject|race|all|any] -> 正文阅读

[JavaScript知识库]Typescript实现Promise[then|catch|finally|resolve|reject|race|all|any]

🔥TypeScript实现Promise

完整版代码 点我

本文会根据通过查看原生Promise的输出结果来逐步实现自定义myPromise,使用class

为避免出现this指向问题,使用箭头函数

then、catch、Promise.resolve、Promise.reject、all、race、finally

??Promise.prototype.then方法实现

😄then方法是Promise最重要的一个方法,后面的所有方法都要调用此方法

先查看一下原生Promise

const promise = new Promise((resolve, reject) => {
  resolve(111)
})
console.log(promise) // PromiseResult 111 PromiseState fullfilled

由此可知需要传递给Promise构造函数一个函数,并有两个回调函数参数resolve, reject,这里称此函数之为👿executor,两个回调函数分别为成功的回调和失败的回调,Promise有三种状态PromiseState: pending|fulfilled|rejected(并且状态一旦改变不允许再次更改)和一个返回结果PromiseResult可以为任意类型

myPromise

class myPromise {
  static PENDING = 'pending'
  static FULFILLED = 'fulfilled'
  static REJECTED = 'rejected'
  PromiseState: string = myPromise.PENDING
  PromiseResult: any = ''
  resolve = (result: unknown) => {
    if (this.PromiseState !== myPromise.PENDING) return;
    this.PromiseState = myPromise.FULFILLED
    this.PromiseResult = result
  }
  reject = (reason: unknown) => {
    if (this.PromiseState !== myPromise.PENDING) return;
    this.PromiseState = myPromise.REJECTED
    this.PromiseResult = reason
  }
  constructor(executor: Function) {
    executor(this.resolve, this.reject)
  }
}

原生

const resPromise = promise.then(value => {
  console.log(value); // 输出 111
  return value
}, (reason => {
  console.log(reason);
}))
console.log('resPromise', resPromise);
// console Promise {<pending>}
//[[Prototype]]: Promise
//[[PromiseState]]: "fulfilled"
//[[PromiseResult]]: 111

可以看到then方法的返回值也是一个Promise,并且Promise.then里的回调时异步执行的,这里分别给then方法的两个回调函数默认值

class myPromise {
  static PENDING = 'pending'
  static FULFILLED = 'fulfilled'
  static REJECTED = 'rejected'
  PromiseState: string = myPromise.PENDING
  PromiseResult: any = ''
  static defaultOnResolve: Function = (value: unknown) => value
  static defaultOnReject: Function = (reason: any) => {
    throw reason
  }
  resolve = (result: unknown) => {
    if (this.PromiseState !== myPromise.PENDING) return;
    this.PromiseState = myPromise.FULFILLED
    this.PromiseResult = result
  }
  reject = (reason: unknown) => {
    if (this.PromiseState !== myPromise.PENDING) return;
    this.PromiseState = myPromise.REJECTED
    this.PromiseResult = reason
  }
  constructor(executor: Function) {
    executor(this.resolve, this.reject)
  }
  then = (onResolve = myPromise.defaultOnResolve, onReject = myPromise.defaultOnReject): myPromise => {
    return new myPromise((resolve: Function, reject: Function) => {
      setTimeout(() => {
        if (this.PromiseState === myPromise.FULFILLED) {
          resolve(onResolve(this.PromiseResult))
        } else if (this.PromiseState === myPromise.REJECTED) {
          reject(onReject(this.PromiseResult))
        }
      })
    })
  }
}

?Promiseexecutor里的代码是异步时该如何处理?

const promise = new myPromise((resolve, reject) => {
  setTimeout(() => {
    resolve(111)
  }, 1500)
})
promise.then(value => {
  console.log(value); // 永远不会输出
  return value
}, (reason => {
  console.log(reason);
}))

以上代码console.log(value);永远不会输出

为何?这个时候需要仔细看一下整个执行过程,执行then方法时,因为有定时的缘故,所以Promise的状态还是pending,但是目前还未对pending状态进行处理

必须当Promise的状态确定了之后才能执行对应的回调,所以当pending时,把回调进行存储,当执行resolve/reject时,再把存储的回调函数做遍历执行即可

代码:

class myPromise {
  static PENDING = 'pending'
  static FULFILLED = 'fulfilled'
  static REJECTED = 'rejected'
  PromiseState: string = myPromise.PENDING
  PromiseResult: any = ''
  callbacks: Array<{ onResolve: Function, onReject: Function }> = []
  static defaultOnResolve: Function = (value: unknown) => value
  static defaultOnReject: Function = (reason: any) => {
    throw reason
  }
  resolve = (result: unknown) => {
    if (this.PromiseState !== myPromise.PENDING) return;
    this.PromiseState = myPromise.FULFILLED
    this.PromiseResult = result
    // 遍历回调
    this.callbacks.forEach(item => {
      item.onResolve(this.PromiseResult)
    })
  }
  reject = (reason: unknown) => {
    if (this.PromiseState !== myPromise.PENDING) return;
    this.PromiseState = myPromise.REJECTED
    this.PromiseResult = reason
    // 遍历回调
    this.callbacks.forEach(item => {
      item.onReject(this.PromiseResult)
    })
  }
  constructor(executor: Function) {
    executor(this.resolve, this.reject)
  }
  then = (onResolve = myPromise.defaultOnResolve, onReject = myPromise.defaultOnReject): myPromise => {
    return new myPromise((resolve: Function, reject: Function) => {
      setTimeout(() => {
        if (this.PromiseState === myPromise.FULFILLED) {
          resolve(onResolve(this.PromiseResult))
        } else if (this.PromiseState === myPromise.REJECTED) {
          reject(onReject(this.PromiseResult))
        } else if (this.PromiseState === myPromise.PENDING) {
          //存储回调
          this.callbacks.push({
            onResolve: () => {
              resolve(onResolve(this.PromiseResult))
            },
            onReject: () => {
              reject(onReject(this.PromiseResult))
            }
          })
        }
      })
    })
  }
}

?当then方法中返回的是一个Promise对象,能否在后面的then中拿到上面的值呢?

promise.then((value:unknown) => {
  return new myPromise((resolve: Function) => {
    resolve(22222)
  })
}).then((value: unknown) => {
  console.log('value', value) // 能否输出 22222 ?
})

答案是不能,这里拿到的是一个Promise对象,如何拿到预期的值呢?需要在then方法中进行判断,如果值为Promise对象,那么就使用递归再次调用then

完整then

then = (onResolve = myPromise.defaultOnResolve, onReject = myPromise.defaultOnReject): myPromise => {
    return new myPromise((resolve: Function, reject: Function) => {
      setTimeout(() => {
        if (this.PromiseState === myPromise.FULFILLED) {
          try {
            const res = onResolve(this.PromiseResult)
            if (res instanceof myPromise) {
              res.then(resolve, reject)
            } else {
              resolve(res)
            }
          } catch (e) {
            reject(e)
          }
        } else if (this.PromiseState === myPromise.REJECTED) {
          try {
            const res = onReject(this.PromiseResult)
            if (res instanceof myPromise) {
              res.then(resolve, reject)
            } else {
              resolve(res)
            }
          } catch (e) {
            reject(e)
          }
        } else if (this.PromiseState === myPromise.PENDING) {
          this.callbacks.push({
            onResolve: () => {
              try {
                const res = onResolve(this.PromiseResult)
                if (res instanceof myPromise) {
                  res.then(resolve, reject)
                } else {
                  resolve(res)
                }
              } catch (e) {
                reject(e)
              }
            },
            onReject: () => {
              try {
                const res = onReject(this.PromiseResult)
                if (res instanceof myPromise) {
                  res.then(resolve, reject)
                } else {
                  resolve(res)
                }
              } catch (e) {
                reject(e)
              }
            }
          })
        }
      })
    })
  }

Promise.prototype.catch方法实现

由于then方法已经给了默认值,catch方法直接调用then方法即可,成功的回调函数设置成undefined即可

catch = (onReject = myPromise.defaultOnReject) => {
    return this.then(undefined, onReject)
}

Promise.resolve方法实现

此方法属于Promise类的方法,通过类直接调用的,可以将Promise的状态直接设置为成功状态

调用then方法,方法体内直接执行resolve回调即可

static resolve = (value: unknown) => {
    return new myPromise((resolve: Function) => {
        resolve(value)
    })
}

Promise.reject方法实现

Promise.resolve

static reject = (reason: any) => {
    return new myPromise((resolve: Function, reject: Function) => {
        reject(reason)
    })
}

Promise.all方法实现

简介:此方法接收一个Promise对象数组,当所有Promise的结果都为成功时,此方法才返回成功,否则返回失败

数组中Promise是并发执行(可以自己进行验证),但是PromiseResult的结果确是按顺序返回的!

static all(promiseArr: Array<myPromise>): myPromise {
    return new myPromise((resolve: Function, reject: Function) => {
        let PromiseResult: Array<unknown> = []
        promiseArr.forEach((item, index) => {
            item.then((value: unknown) => {
                PromiseResult[index] = value //对应promise对象索引
                if (PromiseResult.length === promiseArr.length) { // 所有都成功了
                    resolve(PromiseResult)
                }
            }, (reason: any) => {
                reject(reason)
            })
        })
    })
}

Promise.race方法实现

Promise.all方法相反,race方法会把最先返回的结果当作返回值

static race(promiseArr: Array<myPromise>): myPromise {
    return new myPromise((resolve: Function, reject: Function) => {
        promiseArr.forEach((item, index) => {
            item.then((value: unknown) => {
                resolve(value)
            }, (reason: any) => {
                reject(reason)
            })
        })
    })
}

Promise.prototype.finally方法实现

此方法会在then/catch后面执行,💝ES2018新增,在此之前,有些代码在then和catch中可能要重复书写,finally出现之后就很好的解决了这个问题

finally = (executor = new Function) => {
    return this.then((value: unknown) => { 
        return myPromise.resolve(executor()).then(() => value) // 为了将值继续传递供链式调用
    }, (reason: any) => {
        return myPromise.resolve(executor()).then(() => { //为了将值继续传递供链式调用
            throw reason
        })
    })
}

??Promise.any方法实现(🆕ES2021新增)

此方法与race方法十分相似,不同的是,race只要有一个reject,就直接返回reject了,但是any是所有的都reject了才reject

static all(promiseArr: Array<myPromise>): myPromise {
    return new myPromise((resolve: Function, reject: Function) => {
        let PromiseResult: Array<unknown> = []
        promiseArr.forEach((item, index) => {
            item.then((value: unknown) => {
                PromiseResult[index] = value
                if (PromiseResult.length === promiseArr.length) {
                    resolve(PromiseResult)
                }
            }, (reason: any) => {
                reject(reason)
            })
        })
    })
}
  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2021-12-26 22:03:48  更:2021-12-26 22:04:11 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 9:38:46-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码