Promise(简介、基本使用、API、手写实现 Promise、async与await)(四)

简介: Promise(简介、基本使用、API、手写实现 Promise、async与await)(四)

5.3.4 同步任务下then()返回结果的实现

官方的then()执行完回调函数后会返回一个Promise对象,但是目前自己实现的Promise在执行完回调函数后不会返回一个Promise对象

let p2 = new Promise( (resolve, reject)=>{
      reject('err')
    } )
    const res2 =  p2.then(val=>{
      console.log(val)
    }, reason=>{
      console.log(reason)
    })
    console.log(res2)

回调函数执行后没有Promise对象返回

then()返回Promise对象的状态,执行成功的回调函数为成功,执行失败的回调函数为失败,return一个Promise对象根据return的Promise对象状态进行判断。

以回调函数为失败的回调函数为例:

// 状态为失败
    if (this.PromiseState === 'rejected') {
      // 获取回调函数执行的结果
      const result = onRejected(this.PromiseResult)
      if (result instanceof Promise) { // 如果是Promise的实例对象
        // 返回的为Promise实例对象,指定了then,那么result状态改变肯定会执行then中回调函数
        result.then(v => {
          resolve(v) // 调用成功函数,改变返回的Promise对象为成功
        }, r => {
          reject(r) // 调用失败函数,改变返回的Promise对象为失败
        })
      } else {
        // 执行的为失败的对调函数,返回的Promise一定为失败
        // 调用返回Promise对象的reject函数改变返回Promise对象的状态和结果
        resolve(result)
      }
    }

测试:

let p2 = new Promise( (resolve, reject)=>{
      reject('err')
    } )
    const res2 =  p2.then(val=>{
      console.log(val)
    }, reason=>{
      console.log(reason)
    })
    console.log(res2)

回调函数返回的为空,返回的Promise对象的状态应该为成功,结果为undefined

回调函数的成功的写法一样:

// 定义 Promise 的 then 方法
Promise.prototype.then = function (onResolved, onRejected) {
  // 执行完then()返回一个Promise对象
  return new Promise((resolve, reject) => {
    // 状态为成功
    if (this.PromiseState === 'fulfilled' || this.PromiseState === 'resolved') {
      const result = onResolved(this.PromiseResult)
      if (result instanceof Promise) { // 如果是Promise的实例对象
        // 返回的为Promise实例对象,指定了then,那么result状态改变肯定会执行then中回调函数
        result.then(v => {
          resolve(v) // 调用成功函数,改变返回的Promise对象为成功
        }, r => {
          reject(r) // 调用失败函数,改变返回的Promise对象为失败
        })
      } else {
        // 执行的为失败的对调函数,返回的Promise一定为失败
        // 调用返回Promise对象的reject函数改变返回Promise对象的状态和结果
        resolve(result)
      }
    }
    // 状态为失败
    if (this.PromiseState === 'rejected') {
      // 获取回调函数执行的结果
      const result = onRejected(this.PromiseResult)
      if (result instanceof Promise) { // 如果是Promise的实例对象
        // 返回的为Promise实例对象,指定了then,那么result状态改变肯定会执行then中回调函数
        result.then(v => {
          resolve(v) // 调用成功函数,改变返回的Promise对象为成功
        }, r => {
          reject(r) // 调用失败函数,改变返回的Promise对象为失败
        })
      } else {
        // 执行的为失败的对调函数,返回的Promise一定为失败
        // 调用返回Promise对象的reject函数改变返回Promise对象的状态和结果
        reject(result)
      }
    }
    // 状态为 pending
    if (this.PromiseState === 'pending') {
      this.callback.push({
        onResolved: onResolved,
        onRejected: onRejected
      })
    }
  })
}

测试:

let p1 = new Promise( (resolve, reject)=>{
        resolve('OK')
    } )
    const res1 = p1.then(val=>{
      console.log(val)
    }, reason=>{
      console.log(reason)
    })
    console.log(res1)
    let p2 = new Promise( (resolve, reject)=>{
      reject('err')
    } )
    const res2 =  p2.then(val=>{
      console.log(val)
    }, reason=>{
      console.log(reason)
    })
    console.log(res2)

抛出错误处理:

// 状态为失败
    if (this.PromiseState === 'rejected') {
      try {
        // 获取回调函数执行的结果
        const result = onRejected(this.PromiseResult)
        if (result instanceof Promise) { // 如果是Promise的实例对象
          // 返回的为Promise实例对象,指定了then,那么result状态改变肯定会执行then中回调函数
          result.then(v => {
            resolve(v) // 调用成功函数,改变返回的Promise对象为成功
          }, r => {
            reject(r) // 调用失败函数,改变返回的Promise对象为失败
          })
        } else {
          // 执行的为失败的对调函数,返回的Promise一定为失败
          // 调用返回Promise对象的reject函数改变返回Promise对象的状态和结果
          reject(result)
        }
      } catch (e) {
        // 抛出错误状态就为失败
        reject(e)
      }
    }

测试:

let p1 = new Promise( (resolve, reject)=>{
        resolve('OK')
    } )
    const res1 = p1.then(val=>{
      console.log(val)
      throw 'error'
    }, reason=>{
      console.log(reason)
    })
    console.log(res1)
    let p2 = new Promise( (resolve, reject)=>{
      reject('err')
    } )
    const res2 =  p2.then(val=>{
      console.log(val)
    }, reason=>{
      console.log(reason)
      throw 'error'
    })
    console.log(res2)

执行流程图

5.3.5 异步任务下then()返回结果的实现

异步任务下then()不会返回有状态的Promise的对象

let p1 = new Promise((resolve, reject) => {
        setTimeout(() => {
          resolve('OK')
        }, 1000)
      })
      const res1 = p1.then(
        (val) => {
          console.log(val)
        },
        (reason) => {
          console.log(reason)
        }
      )
      console.log(res1)

因为回调函数最终执行是在调用then方法对象中的resolve或reject函数中执行

所以对保存的回调函数进行修改,让其调用将要返回的Promise对象的resolve函数或reject函数。

需要对调用then的Promise对象进行保存

// 定义 Promise 的 then 方法
Promise.prototype.then = function (onResolved, onRejected) {
  const self = this // 保存调用then的Promise对象
  ......
}

在保存的函数中调用成功或失败的回调函数,并且执行返回的Promise对象的状态和结果的修改

// 状态为 pending
    if (this.PromiseState === 'pending') {
      this.callback.push({
        onResolved: function () {
          // 执行成功的回调函数
          // 根据回调函数的结果进行判断,来修改返回对象的状态
          const result = onResolved(self.PromiseResult)
          // 判断
          if (result instanceof Promise) { // 如果是Promise的实例对象
            result.then(v => {
              resolve(v) // 调用成功函数,改变返回的Promise对象为成功
            }, r => {
              reject(r) // 调用失败函数,改变返回的Promise对象为失败
            })
          } else {
            resolve(result)
          }
        },
        onRejected: function () {
          // 执行失败的回调函数
          const result = onResolved(self.PromiseResult)
          // 判断
          if (result instanceof Promise) { // 如果是Promise的实例对象
            result.then(v => {
              resolve(v) // 调用成功函数,改变返回的Promise对象为成功
            }, r => {
              reject(r) // 调用失败函数,改变返回的Promise对象为失败
            })
          } else {
            resolve(result)
          }
        }
      })
    }

测试:

let p1 = new Promise((resolve, reject) => {
        setTimeout(() => {
          resolve('OK')
        }, 1000)
      })
      const res1 = p1.then(
        (val) => {
          console.log(val)
        },
        (reason) => {
          console.log(reason)
        }
      )
      console.log(res1)
      let p2 = new Promise((resolve, reject) => {
        setTimeout(() => {
          reject('OK')
        }, 1000)
      })
      const res2 = p2.then(
        (val) => {
          console.log(val)
        },
        (reason) => {
          console.log(reason)
        }
      )
      console.log(res2)

抛出错误返回的Promise对象

// 状态为 pending
    if (this.PromiseState === 'pending') {
      this.callback.push({
        onResolved: function () {
          try {
            // 执行成功的回调函数
            // 根据回调函数的结果进行判断,来修改返回对象的状态
            const result = onResolved(self.PromiseResult)
            // 判断
            if (result instanceof Promise) { // 如果是Promise的实例对象
              result.then(v => {
                resolve(v) // 调用成功函数,改变返回的Promise对象为成功
              }, r => {
                reject(r) // 调用失败函数,改变返回的Promise对象为失败
              })
            } else {
              resolve(result)
            }
          } catch (e) {
            reject(e)
          }
        },
        onRejected: function () {
          try {
            // 执行失败的回调函数
            const result = onResolved(self.PromiseResult)
            // 判断
            if (result instanceof Promise) { // 如果是Promise的实例对象
              result.then(v => {
                resolve(v) // 调用成功函数,改变返回的Promise对象为成功
              }, r => {
                reject(r) // 调用失败函数,改变返回的Promise对象为失败
              })
            } else {
              resolve(result)
            }
          } catch (e) {
            reject(e)
          }
        }

测试:

let p1 = new Promise((resolve, reject) => {
        setTimeout(() => {
          resolve('OK')
        }, 1000)
      })
      const res1 = p1.then(
        (val) => {
          console.log(val)
          throw 'ERROR'
        },
        (reason) => {
          console.log(reason)
        }
      )
      console.log(res1)

5.3.6 then()代码优化

会发现三个if中的代码类似,就回调函数有所不同,可以写到外面封装为函数,利于后期维护

注意this的指向

// 定义 Promise 的 then 方法
Promise.prototype.then = function (onResolved, onRejected) {
  const self = this // 保存调用then的Promise对象
  // 执行完then()返回一个Promise对象
  return new Promise((resolve, reject) => {
    // 封装函数
    function callback(type) {
      try {
        // 使用this,this指向的不为调用then的Promise对象
        const result = type(self.PromiseResult)
        if (result instanceof Promise) { // 如果是Promise的实例对象
          result.then(v => {
            resolve(v) // 调用成功函数,改变返回的Promise对象为成功
          }, r => {
            reject(r) // 调用失败函数,改变返回的Promise对象为失败
          })
        } else {
          resolve(result)
        }
      } catch (e) {
        reject(e)
      }
    }
    // 状态为成功
    if (this.PromiseState === 'fulfilled' || this.PromiseState === 'resolved') {
      callback(onResolved)
    }
    // 状态为失败
    if (this.PromiseState === 'rejected') {
      callback(onRejected)
    }
    // 状态为 pending
    if (this.PromiseState === 'pending') {
      this.callback.push({
        onResolved: function () {
          callback(onResolved)
        },
        onRejected: function () {
          callback(onRejected)
        }
      })
    }
  })
}

相关文章
|
6月前
|
前端开发 JavaScript API
一文吃透 Promise 与 async/await,异步编程也能如此简单!建议收藏!
在前端开发中,异步编程至关重要。本文详解了同步与异步的区别,通过生活化例子帮助理解。深入讲解了 Promise 的概念、状态及链式调用,并引入 async/await 这一语法糖,使异步代码更清晰易读。还介绍了多个异步任务的组合处理方式,如 Promise.all 与 Promise.race。掌握这些内容,将大幅提升你的异步编程能力,写出更优雅、易维护的代码,助力开发与面试!
359 0
一文吃透 Promise 与 async/await,异步编程也能如此简单!建议收藏!
|
6月前
|
前端开发 JavaScript API
JavaScript异步编程:从Promise到async/await
JavaScript异步编程:从Promise到async/await
556 204
|
12月前
|
前端开发
使用 async/await 结合 try/catch 处理 Promise.reject()抛出的错误时,有什么需要注意的地方?
使用 async/await 结合 try/catch 处理 Promise.reject()抛出的错误时,有什么需要注意的地方?
649 155
|
前端开发 JavaScript 开发者
Async 和 Await 是基于 Promise 实现
【10月更文挑战第30天】Async和Await是基于Promise实现的语法糖,它们通过简洁的语法形式,借助Promise的异步处理机制,为JavaScript开发者提供了一种更优雅、更易于理解和维护的异步编程方式。
336 1
|
10月前
|
前端开发 安全 JavaScript
Promise 这个新 API 真香!
本文首发于公众号【沉浸式趣谈】,探讨 ES2025 新特性 `Promise.try()` 的强大功能。该方法可将同步或异步函数统一包装为 Promise,解决同步错误捕获难题,简化代码逻辑。通过实际案例分析,展示其在 API 调用、混合任务链及文件操作中的应用优势。`Promise.try()` 让 Promise 使用更健壮、一致,是开发者工具箱的有力补充。更多技术分享,请访问我的博客 https://yaolifeng.com 或点赞、评论、转发支持!
210 13
|
前端开发
如何使用async/await解决Promise的缺点?
总的来说,`async/await` 是对 Promise 的一种很好的补充和扩展,它为我们提供了更高效、更易读、更易维护的异步编程方式。通过合理地运用 `async/await`,我们可以更好地解决 Promise 的一些缺点,提升异步代码的质量和开发效率。
284 64
|
前端开发 JavaScript
async/await和Promise在性能上有什么区别?
性能优化是一个综合性的工作,除了考虑异步模式的选择外,还需要关注代码的优化、资源的合理利用等方面。
499 63
|
API 计算机视觉
MLDL之API:关于各国内外大平台API简介、使用方法之详细攻略
MLDL之API:关于各国内外大平台API简介、使用方法之详细攻略
|
4月前
|
缓存 监控 前端开发
顺企网 API 开发实战:搜索 / 详情接口从 0 到 1 落地(附 Elasticsearch 优化 + 错误速查)
企业API开发常陷参数、缓存、错误处理三大坑?本指南拆解顺企网双接口全流程,涵盖搜索优化、签名验证、限流应对,附可复用代码与错误速查表,助你2小时高效搞定开发,提升响应速度与稳定性。