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
Promise、async和await
Promise、async和await
11 0
|
1月前
|
前端开发 小程序 API
【微信小程序】-- 使用 npm 包 - API Promise化(四十二)
【微信小程序】-- 使用 npm 包 - API Promise化(四十二)
|
1月前
|
数据采集 前端开发 JavaScript
如何在爬虫过程中正确使用Promise对象和async/await?
如何在爬虫过程中正确使用Promise对象和async/await?
20 2
|
1月前
|
前端开发 JavaScript 开发者
JavaScript 中的异步编程:Promise 和 Async/Await
在现代的 JavaScript 开发中,异步编程是至关重要的。本文将介绍 JavaScript 中的异步编程概念,重点讨论 Promise 和 Async/Await 这两种常见的处理异步操作的方法。通过本文的阐述,读者将能够更好地理解和应用这些技术,提高自己在 JavaScript 开发中处理异步任务的能力。
|
4天前
|
前端开发 JavaScript Java
Promise, async, await实现异步编程,代码详解
Promise, async, await实现异步编程,代码详解
16 1
|
25天前
|
前端开发
promise和async的区别是什么?
promise和async的区别是什么?
10 1
|
1月前
|
存储 前端开发 安全
【C++并发编程】std::future、std::async、std::packaged_task与std::promise的深度探索(三)
【C++并发编程】std::future、std::async、std::packaged_task与std::promise的深度探索
26 0
|
1月前
|
存储 设计模式 前端开发
【C++并发编程】std::future、std::async、std::packaged_task与std::promise的深度探索(二)
【C++并发编程】std::future、std::async、std::packaged_task与std::promise的深度探索
30 0
|
1月前
|
并行计算 前端开发 安全
【C++并发编程】std::future、std::async、std::packaged_task与std::promise的深度探索(一)
【C++并发编程】std::future、std::async、std::packaged_task与std::promise的深度探索
64 0