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

相关文章
|
1天前
|
前端开发 JavaScript
在 Vue 中,Promise 和 async/await 有什么不同?
在 Vue 中,Promise 和 async/await 有什么不同?
7 0
|
4天前
|
前端开发 JavaScript API
JavaScript学习笔记(一)promise与async
JavaScript学习笔记(一)promise与async
|
13天前
|
前端开发 JavaScript
JavaScript 中的异步编程:Promise 和 Async/Await 的实现与应用
在Web开发中,JavaScript异步编程是一个不可忽视的重要话题。本文将深入探讨JavaScript中Promise和Async/Await的实现原理与应用场景,通过实例代码带您了解如何优雅地处理异步操作,提升代码的可读性和可维护性。
|
1月前
|
前端开发 JavaScript
处理异步请求的 async/await 和 promise
处理异步请求的 async/await 和 promise
|
2月前
|
前端开发 C++
C++11实用技术(三)std::future、std::promise、std::packaged_task、async
C++11实用技术(三)std::future、std::promise、std::packaged_task、async
17 0
|
2月前
|
JavaScript 前端开发 IDE
Vue3【为什么选择Vue框架、Vue简介 、Vue API 风格 、Vue开发前的准备 、Vue项目目录结构 、模板语法、属性绑定 、 】(一)-全面详解(学习总结---从入门到深化)
Vue3【为什么选择Vue框架、Vue简介 、Vue API 风格 、Vue开发前的准备 、Vue项目目录结构 、模板语法、属性绑定 、 】(一)-全面详解(学习总结---从入门到深化)
38 1
|
2月前
|
前端开发 JavaScript
【面试题】async/await、promise和setTimeout的执行顺序
【面试题】async/await、promise和setTimeout的执行顺序
|
2月前
|
前端开发 JavaScript 开发者
【面试题】前端人70%以上 不了解的promise/async await
【面试题】前端人70%以上 不了解的promise/async await
|
JSON API 数据格式

相关产品

  • 云迁移中心