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)
        }
      })
    }
  })
}

相关文章
|
2月前
|
前端开发 JavaScript 开发者
Async 和 Await 是基于 Promise 实现
【10月更文挑战第30天】Async和Await是基于Promise实现的语法糖,它们通过简洁的语法形式,借助Promise的异步处理机制,为JavaScript开发者提供了一种更优雅、更易于理解和维护的异步编程方式。
40 1
|
2月前
|
前端开发
如何使用async/await解决Promise的缺点?
总的来说,`async/await` 是对 Promise 的一种很好的补充和扩展,它为我们提供了更高效、更易读、更易维护的异步编程方式。通过合理地运用 `async/await`,我们可以更好地解决 Promise 的一些缺点,提升异步代码的质量和开发效率。
40 5
|
2月前
|
前端开发 JavaScript
async/await和Promise在性能上有什么区别?
性能优化是一个综合性的工作,除了考虑异步模式的选择外,还需要关注代码的优化、资源的合理利用等方面。
45 4
|
2月前
|
JSON 前端开发 JavaScript
浅谈JavaScript中的Promise、Async和Await
【10月更文挑战第30天】Promise、Async和Await是JavaScript中强大的异步编程工具,它们各自具有独特的优势和适用场景,开发者可以根据具体的项目需求和代码风格选择合适的方式来处理异步操作,从而编写出更加高效、可读和易于维护的JavaScript代码。
40 1
|
3月前
|
前端开发 JavaScript
setTimeout、Promise、Async/Await 的区别
`setTimeout` 是用于延迟执行函数的简单方法;`Promise` 表示异步操作的最终完成或失败;`Async/Await` 是基于 Promise 的语法糖,使异步代码更易读和维护。三者都用于处理异步操作,但使用场景和语法有所不同。
|
3月前
|
前端开发 JavaScript 开发者
JavaScript 中的异步编程:深入了解 Promise 和 async/await
【10月更文挑战第8天】JavaScript 中的异步编程:深入了解 Promise 和 async/await
|
3月前
|
前端开发 JavaScript UED
深入了解JavaScript异步编程:回调、Promise与async/await
【10月更文挑战第11天】深入了解JavaScript异步编程:回调、Promise与async/await
31 0
|
前端开发 JavaScript API
Promise API 简介
Promise API 简介 译者注: 到处是回调函数,代码非常臃肿难看, Promise 主要用来解决这种编程方式, 将某些代码封装于内部。
1014 0
|
6天前
|
JSON 前端开发 搜索推荐
关于商品详情 API 接口 JSON 格式返回数据解析的示例
本文介绍商品详情API接口返回的JSON数据解析。最外层为`product`对象,包含商品基本信息(如id、name、price)、分类信息(category)、图片(images)、属性(attributes)、用户评价(reviews)、库存(stock)和卖家信息(seller)。每个字段详细描述了商品的不同方面,帮助开发者准确提取和展示数据。具体结构和字段含义需结合实际业务需求和API文档理解。
|
11天前
|
JSON API 数据格式
京东商品SKU价格接口(Jd.item_get)丨京东API接口指南
京东商品SKU价格接口(Jd.item_get)是京东开放平台提供的API,用于获取商品详细信息及价格。开发者需先注册账号、申请权限并获取密钥,随后通过HTTP请求调用API,传入商品ID等参数,返回JSON格式的商品信息,包括价格、原价等。接口支持GET/POST方式,适用于Python等语言的开发环境。
63 11