Loading... # Promise封装,一行一注释 ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Document</title> <!-- 引入我们自己封装的Promise文件,文件定义里面 Promise,这时系统自带的Promise失效--> <script src="./myPromise.js"></script> </head> <body></body> <script> const p = new Promise((resolve, reject) => { // 同步函数resolve // resolve('ok1') // 同步函数reject // reject('err') // 异步函数测试 // setTimeout(() => { // 异步函数resolve // resolve('ok') // 异步函数reject // resolve('error') // }, 1000) }) // 链式调用 const res = p.then( // resolve回调 value => { // resolve('ok') 则value输出ok // console.log(value) // 返回另外一个Promise对象 // return new Promise((resolve, reject) => { // promise执行异步函数 // setTimeout(() => { // resolve('promise ok') // console.log(value) // }, 1000) // }) // 执行resolve()错误抛出 // throw "FAIL1" }, // reject回调 reason => { // reject('err') 则reason输出err // console.log(reason) // 执行reject()错误抛出 // throw "FAIL2" } ) // 输出res 查看Premise状态 console.log(res) </script> </html> ``` ```js // 封装Promise // 声明构造函数 // 注:这里声明的函数会直接把系统的Promise函数覆盖 function Promise(execltor) { // 状态开始为pending this.PromiseState = 'pending' // 返回值开始为null this.PromiseResult = null // 声明属性,保存回调函数 this.callback = [] // 锁定this,这里this指向Promise对象 // 参考:如果是在new中调用,this则为新创建的对象 // 若resolve/reject为箭头函数,此处可省略 const _this = this // resolve函数 function resolve(data) { // 状态改变,则不可逆 if (_this.PromiseState !== 'pending') return // 改变pending状态为resolved _this.PromiseState = 'resolved' // 传入data _this.PromiseResult = data // 这里对应then函数 如果Promise传入的是一个异步代码 // 那么PromiseState就是一个pending状态 // 所以要再次执行调用Promise,直到PromiseState为resolved或者resolved为止 // 这里传入data用于下一次执行Promise的传参 _this.callback.forEach(item => { item.onResolved(data) }) } // reject函数 function reject(data) { // 状态改变,则不可逆 if (_this.PromiseState !== 'pending') return // 改变pending状态为rejected _this.PromiseState = 'rejected' // 传入data _this.PromiseResult = data _this.callback.forEach(item => { item.onRejected(data) }) } // 抛出异常处理 try { // 同步调用execltor execltor(resolve, reject) } catch (error) { // 修改promise对象状态为失败 reject(error) } } // 核心:then函数 传入成功会执行的代码和失败会执行的代码 Promise.prototype.then = function (onResolved, onRejected) { // 返回Promise对象 用于链式调用 return new Promise((resolve, reject) => { // 封装函数 用于状态为resolved时或rejected时执行 // type 当状态为resolved则为onResolved(this.PromiseResult) // 当状态为rejected则为onRejected(this.PromiseResult) // handle函数作用:判断是否是Promise对象,如果不是,改变状态,传出结果 // 如果是,继续调用then 另捕捉throw传出的错误且改变状态 const handle = type => { // 错误处理 用于捕捉throw 'FAIL' try { // 执行成功/失败会执行的函数 let result = type(this.PromiseResult) // 若返回值为Promise对象,则继续递归执行then if (result instanceof Promise) { // 链式调用then,传入成功和失败代码片段 result.then( v => { resolve(v) }, r => { reject(r) } ) } else { // 如果不是Promise对象,改变状态,传出result resolve(result) } } catch (error) { // 如果是throw,直接失败,传出抛出的error reject(error) } } // 调用回调函数 // 如果状态为resolved if (this.PromiseState === 'resolved') { // 使用handle改变状态 确定结果 handle(onResolved) } // 如果状态为rejected if (this.PromiseState === 'rejected') { // 使用handle改变状态 确定结果 handle(onRejected) } // 如果状态为pending // 代表着Promise里面传入的为异步函数 if (this.PromiseState === 'pending') { // 将需要执行的异步函数存入callback数组 // 当异步函数结束,调用resolve / reject时,对应上面this.callback.forEach执行 this.callback.push({ onResolved: () => { handle(onResolved) }, onRejected: () => { handle(onRejected) }, }) } }) } ``` 最后修改:2022 年 09 月 15 日 © 允许规范转载 赞 1 如果觉得我的文章对你有用,请随意赞赏