iis服务器助手广告广告
返回顶部
首页 > 资讯 > 前端开发 > JavaScript >JavaScript手写Promise核心原理
  • 347
分享到

JavaScript手写Promise核心原理

2024-04-02 19:04:59 347人浏览 独家记忆
摘要

目录准备完善 resolve/rejectthen异步处理链式调用边界处理catch优化后完整代码准备 首先,promise 有三种状态:pending fulf

准备

  • 首先,promise 有三种状态:pending fulfilled rejected;
  • promise在实例化操作中, 有两个改变状态的方法,分别为resolve,reject;
  • promise有很多方法,详情请见 mdn, 本篇文章先实现 promise的核心apithencatch;

我们使用 es6 提供的 class 来实现

class MyPromise {
 // 准备三个状态
 static PENDING = 'pending';
 static FULFILLED = 'fulfilled';
 static REJECTED = 'rejected';

 constructor(executor) {
   this.status = MyPromise.PENDING; // 表示promise的状态
   this.value = null;  // 表示promise的值
   try {
     executor(this.resolve.bind(this), this.reject.bind(this))
   } catch (error) {
     this.reject(error)
   }
 }
 resolve() {
 }
 reject() {
 }
}

在这里 executor 就是传递过来的函数,可以接收 resolvereject,这里将内部的两个方法给传入,如果在调用的过程中报错了会调用reject方法

完善 resolve/reject

他们做的工作分为以下几部

  • 将状态改为pendingfulfilled 或 rejected
  • 可以接受一个值为当前的promisevalue
  resolve(value) {
    if (this.status === MyPromise.PENDING) {
      this.status = MyPromise.FULFILLED;
      this.value = value
    }
  }
  reject(value) {
    if (this.status === MyPromise.PENDING) {
      this.status = MyPromise.REJECTED;
      this.value = value
    }
  }

then

then 函数可以接受两个参数,分别为成功的回调函数和失败的回调函数,并且回调函数的默认为一个函数

  • 状态为 fulfilled 执行第一个回调,rejected 执行第二个回调
  • 回调函数中给传入当前的 value
  • then的执行为异步的
  then(onFulfilled, onRejected) {
    if (typeof onFulfilled !== 'function') {
      onFulfilled = value => value
    }

    if (typeof onFulfilled !== 'function') {
      onRejected = value => value
    }

    if (this.status === MyPromise.FULFILLED) {
      setTimeout(() => {
        onFulfilled(this.value)
      })
    }

    if (this.status === MyPromise.REJECTED) {
      setTimeout(() => {
        onRejected(this.value)
      })
    }
  }

验证一下:

console.log(1)
new MyPromise((resolve, reject) => {
  console.log(2)
  resolve('成功')
}).then(res => console.log(res))

console.log(3)

// 打印 1 2 3 成功

promise里面有异步代码的时候,这个时候运行到.then方法 状态为pending,下来增加一下异步任务的处理

异步处理

当状态为pending的时候,表示执行的是异步任务,这个时候我们可以增加一个callback,把异步执行的内容添加到这个callback中,当执行完异步代码的时候,会执行异步函数的callback的任务

constructor(executor) {
  // ...
  this.callbacks = []; // 用来存储回调函数的容器
  // ...
}
resolve(value) {
  // ...
  this.callbacks.forEach(({ onFulfilled }) => onFulfilled(value)) 
  // 当执行到这里的时候 如果有onFulfilled 就说明已经执行完then方法给容器添加内容了。把resolve的值传递给onFulfilled
} 
reject(value) {
  // ...
  this.callbacks.forEach(({ onRejected }) => onRejected(value))
  // 当执行到这里的时候 如果有onRejected 就说明已经执行完then方法给容器添加内容了。把reject的值传递给onFulfilled
}
then(onFulfilled, onRejected) {
  // ...
  if (this.status === MyPromise.PENDING) {
    this.callbacks.push({
      onFulfilled: value => {
        setTimeout(() => {
          onFulfilled(value)
        })
      },
      onRejected: value => {
        setTimeout(() => {
          onRejected(value)
        })
      }
    })
  }
 }

验证一下:

new MyPromise((resolve, reject) => {
  setTimeout(() => {
    resolve('成功')
  })
}).then(res => console.log(res)) 

// 打印  成功

then 函数可以链式调用,接下来我们完善一下

链式调用

链式调用的核心就是返回一个新的 promise,当成功调用的时候调用新的promiseresolve,失败reject,并且链式调用会把前一个的返回值当作下一个的 resolve 的状态

then(onFulfilled, onRejected) {
    if (typeof onFulfilled !== 'function') {
      onFulfilled = value => value
    }

    if (typeof onFulfilled !== 'function') {
      onRejected = value => value
    }
    return new MyPromise((resolve, reject) => {
      if (this.status === MyPromise.FULFILLED) {
        setTimeout(() => {
          const result = onFulfilled(this.value)
          resolve(result)
        })
      }

      if (this.status === MyPromise.REJECTED) {
        setTimeout(() => {
          const result = onRejected(this.value)
          resolve(result) 
        })
      }
      if (this.status === MyPromise.PENDING) {
        this.callbacks.push({
          onFulfilled: value => {
            setTimeout(() => {
              const result = onFulfilled(value)
              resolve(result)
            })
          },
          onRejected: value => {
            setTimeout(() => {
              const result = onRejected(value)
              resolve(result)
            })
          }
        })
      }
    })
  }

验证一下:

new MyPromise((resolve, reject) => {
  setTimeout(() => {
    reject('失败')
  })
}).then(res => res, err => err).then(res => console.log(res))

// 打印  失败

如果.then的回调函数返回的是promise的情况也要做个处理

边界处理

实现前:

new MyPromise((resolve, reject) => {
  setTimeout(() => {
    resolve('成功')
  })
}).then(
  res => new MyPromise((resolve, reject) => {
    resolve(res)
  }),
  err => err
).then(res => console.log(res))

// 打印  { "status": "fulfilled", "value": "成功", "callbacks": [] }

当判断返回值为 MyPromise 的时候,需要手动调用 .then 的方法取他的值,并且吧当前的 promise 的改变状态的函数透出给 then 方法

  then(onFulfilled, onRejected) {
    if (typeof onFulfilled !== 'function') {
      onFulfilled = value => value
    }

    if (typeof onFulfilled !== 'function') {
      onRejected = value => value
    }
    return new MyPromise((resolve, reject) => {
      if (this.status === MyPromise.FULFILLED) {
        setTimeout(() => {
          const result = onFulfilled(this.value)
          if (result instanceof MyPromise) { 
            result.then(resolve, reject)
          } else {
            resolve(result)
          }
        })
      }

      if (this.status === MyPromise.REJECTED) {
        setTimeout(() => {
          const result = onRejected(this.value)
          if (result instanceof MyPromise) {
            result.then(resolve, reject)
          } else {
            resolve(result)
          }
        })
      }

      if (this.status === MyPromise.PENDING) {
        this.callbacks.push({
          onFulfilled: value => {
            setTimeout(() => {
              const result = onFulfilled(value)
               if (result instanceof MyPromise) {
                 result.then(resolve, reject)
               } else {
                resolve(result)
               }
            })
          },
          onRejected: value => {
            setTimeout(() => {
              const result = onRejected(value)
              if (result instanceof MyPromise) {
                result.then(resolve, reject)
              } else {
                resolve(result)
              }
            })
          }
        })
      }
    })
  }

验证:

new MyPromise((resolve, reject) => {
  setTimeout(() => {
    resolve('成功')
  })
}).then(
  res => new MyPromise((resolve, reject) => {
    resolve(res)
  }),
  err => err
).then(res => console.log(res))

// 打印  成功

到这里 .then 方法就实现差不多了,接下来实现 catch 方法

catch

catch 方法可以处理拒绝的状态和错误的状态:

  catch(onFulfilled) {
    if (typeof onFulfilled !== 'function') {
      onFulfilled = value => value
    }

    return new MyPromise((resolve, reject) => {
      if (this.status === MyPromise.REJECTED) {
        setTimeout(() => {
          const result = onFulfilled(this.value)
          if (result instanceof MyPromise) {
            result.then(resolve, reject)
          } else {
            resolve(result)
          }
        })
      }
    })
  }

验证:

new MyPromise((resolve, reject) => {
  reject('失败')
}).catch(res=> console.log(res))

// 打印  失败

道理其实和 then 是相同的,到这里主功能基本上就差不多了,但是有很多重复的地方,优化一下

优化后完整代码

class MyPromise {
  // 准备三个状态
  static PENDING = 'pending';
  static FULFILLED = 'fulfilled';
  static REJECTED = 'rejected';

  constructor(executor) {
    this.status = MyPromise.PENDING; // 表示promise的状态
    this.value = null;  // 表示promise的值
    this.callbacks = [];
    try {
      executor(this.resolve.bind(this), this.reject.bind(this))
    } catch (error) {
      console.log(error)
      this.reject(error)
    }
  }
  resolve(value) {
    if (this.status === MyPromise.PENDING) {
      this.status = MyPromise.FULFILLED;
      this.value = value
    }
    this.callbacks.forEach(({ onFulfilled }) => onFulfilled(value))
  }
  reject(value) {
    if (this.status === MyPromise.PENDING) {
      this.status = MyPromise.REJECTED;
      this.value = value
    }
    this.callbacks.forEach(({ onRejected }) => onRejected(value))
  }
  parse({ callback, resolve, reject, value = this.value }) {
    setTimeout(() => {
      const result = callback(value)
      if (result instanceof MyPromise) {
        result.then(resolve, reject)
      } else {
        resolve(result)
      }
    })
  }
  then(onFulfilled, onRejected) {
    if (typeof onFulfilled !== 'function') {
      onFulfilled = value => value
    }

    if (typeof onFulfilled !== 'function') {
      onRejected = value => value
    }
    return new MyPromise((resolve, reject) => {
      if (this.status === MyPromise.FULFILLED) {
        this.parse({ callback: onFulfilled, resolve, reject })
      }

      if (this.status === MyPromise.REJECTED) {
        this.parse({ callback: onRejected, resolve, reject })
      }

      if (this.status === MyPromise.PENDING) {
        this.callbacks.push({
          onFulfilled: value => {
            this.parse({ callback: onFulfilled, resolve, reject, value })
          },
          onRejected: value => {
            this.parse({ callback: onRejected, resolve, reject, value })
          }
        })
      }
    })
  }
  catch(onFulfilled) {
    if (typeof onFulfilled !== 'function') {
      onFulfilled = value => value
    }

    return new MyPromise((resolve, reject) => {
      if (this.status === MyPromise.REJECTED) {
        this.parse({ callback: onFulfilled, resolve, reject })
      }
    })
  }
}

到此这篇关于javascript手写Promise核心原理的文章就介绍到这了,更多相关JavaScript Promise内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: JavaScript手写Promise核心原理

本文链接: https://www.lsjlt.com/news/152441.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • JavaScript手写Promise核心原理
    目录准备完善 resolve/rejectthen异步处理链式调用边界处理catch优化后完整代码准备 首先,promise 有三种状态:pending fulf...
    99+
    2024-04-02
  • JavaScript怎么实现手写promise
    这篇文章主要介绍了JavaScript怎么实现手写promise的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇JavaScript怎么实现手写promise文章都会有所收获,下面我们一起来看看吧。需求我们先来总...
    99+
    2023-07-06
  • javascript核心是什么写的
    随着互联网的发展,JavaScript已经成为了一个非常重要的程序设计语言,不仅仅在Web开发中占据了重要地位,同时也在桌面程序开发、服务器端编程和游戏开发等领域得到了广泛应用。而JavaScript的成功之处在于,它不仅仅是一门语言,更是...
    99+
    2023-05-14
  • 万字详解JavaScript手写一个Promise
    目录前言Promise核心原理实现Promise的使用分析MyPromise的实现在Promise中加入异步操作实现then方法的多次调用实现then的链式调用then方法链式调用识...
    99+
    2024-04-02
  • 怎么使用JavaScript手写一个Promise
    这篇文章主要介绍“怎么使用JavaScript手写一个Promise”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“怎么使用JavaScript手写一个Promise”文章能帮助大家解决问题。Prom...
    99+
    2023-07-02
  • javascript中Promise原理是什么
    本篇内容主要讲解“javascript中Promise原理是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“javascript中Promise原理是什么”吧...
    99+
    2024-04-02
  • JavaScript实现手写promise的示例代码
    目录背景需求then的链式调用Promise.all背景 promise 作为前端开发中常用的函数,解决了 js 处理异步时回调地狱的问题,大家应该也不陌生了,今天来学习一下 pro...
    99+
    2023-05-15
    JavaScript手写promise JavaScript promise
  • JavaScript面试必考之实现手写Promise
    目录Promise手写框架完整代码测试resolverejectPromise手写 Promise作为面试必考题,Promise的手写也是面试官必问的问题,所以对于Promise我们...
    99+
    2022-12-08
    JavaScript实现手写Promise JavaScript手写Promise JavaScript Promise
  • ReentrantLock核心原理是什么
    本篇内容介绍了“ReentrantLock核心原理是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!&n...
    99+
    2024-04-02
  • Axios核心原理是什么
    这篇文章主要介绍“Axios核心原理是什么”,在日常操作中,相信很多人在Axios核心原理是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Axios核心原理是什么”的疑惑...
    99+
    2024-04-02
  • ReactHook核心原理是什么
    本篇内容主要讲解“ReactHook核心原理是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“ReactHook核心原理是什么”吧!基本准备工作手写useSt...
    99+
    2024-04-02
  • JavaScript 原型模式的精髓:解读其核心理念
    原型模式是 JavaScript 面向对象编程中的核心概念之一,它提供了创建和管理对象非常便捷的方法: 理解原型模式的基础知识——原型、原型链、构造函数等是 JavaScript 原型模式的基础概念,理解这些概念对于掌握原型模式至关重要...
    99+
    2024-02-06
    JavaScript 原型 对象 属性 方法
  • React的核心原理和用法
    本篇内容介绍了“React的核心原理和用法”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成! 1. ...
    99+
    2024-04-02
  • Zookeeper的核心原理是什么
    这篇文章主要介绍“Zookeeper的核心原理是什么”,在日常操作中,相信很多人在Zookeeper的核心原理是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Zookee...
    99+
    2024-04-02
  • Docker核心原理之 Cgroup详解
    内核中强大的工具cgroup,不仅可以限制被NameSpace隔离起来的资源,还可以为资源设置权重,计算用量等 什么是cgroup cgroup全称是control groups c...
    99+
    2024-04-02
  • Vue的核心原理是什么
    这篇文章主要介绍“Vue的核心原理是什么”,在日常操作中,相信很多人在Vue的核心原理是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Vue的核心原理是什么”的疑惑有所帮助!接下来,请跟着小编一起来学习吧...
    99+
    2023-06-29
  • 如何理解golang里面的读写锁实现与核心原理
    如何理解golang里面的读写锁实现与核心原理,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。基础筑基读写锁的特点读写锁区别与互斥锁的主要区别就是读锁之间是共享的...
    99+
    2023-06-19
  • JavaScript面试必备技巧之手写一个Promise
    目录基本实现实现resolve和reject状态不可变then其他方法很多同学在面试的时候都会被要求手写一个Promise,那么今天我总结了一些手写Promise的方法,可以跟着我的...
    99+
    2023-02-08
    JavaScript实现手写Promise JavaScript手写Promise JavaScript Promise
  • .NET WebSocket核心原理是怎样的
    .NET WebSocket核心原理是怎样的,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。我们先深入研究基本概念,以了解Web...
    99+
    2024-04-02
  • React-Redux的核心原理是什么
    这篇文章主要介绍“React-Redux的核心原理是什么”,在日常操作中,相信很多人在React-Redux的核心原理是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Re...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作