如何通过手写JavaScript实现Promise的核心原理?

2026-04-02 22:261阅读0评论SEO问题
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计1883个文字,预计阅读时间需要8分钟。

如何通过手写JavaScript实现Promise的核心原理?

目录 + 准备 + 完善 + resolve/reject + then + 异步处理 + 链式调用 + 边界处理 + catch + 优化后完整代码 + 准备 + 优先级,Promise + 有三种状态:pending, fulfilled, rejected; Promise + 实例化操作中,有改变状态的两个方法:resolve, reject

目录
  • 准备
  • 完善 resolve/reject
  • then
    • 异步处理
    • 链式调用
    • 边界处理
  • catch
    • 优化后完整代码

      准备

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

      我们使用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

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

      • 将状态改为pendingfulfilledrejected
      • 可以接受一个值为当前的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,下来增加一下异步任务的处理

      如何通过手写JavaScript实现Promise的核心原理?

      异步处理

      当状态为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核心原理的文章就介绍到这了,更多相关JavaScriptPromise内容请搜索自由互联以前的文章或继续浏览下面的相关文章希望大家以后多多支持自由互联!

      本文共计1883个文字,预计阅读时间需要8分钟。

      如何通过手写JavaScript实现Promise的核心原理?

      目录 + 准备 + 完善 + resolve/reject + then + 异步处理 + 链式调用 + 边界处理 + catch + 优化后完整代码 + 准备 + 优先级,Promise + 有三种状态:pending, fulfilled, rejected; Promise + 实例化操作中,有改变状态的两个方法:resolve, reject

      目录
      • 准备
      • 完善 resolve/reject
      • then
        • 异步处理
        • 链式调用
        • 边界处理
      • catch
        • 优化后完整代码

          准备

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

          我们使用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

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

          • 将状态改为pendingfulfilledrejected
          • 可以接受一个值为当前的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,下来增加一下异步任务的处理

          如何通过手写JavaScript实现Promise的核心原理?

          异步处理

          当状态为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核心原理的文章就介绍到这了,更多相关JavaScriptPromise内容请搜索自由互联以前的文章或继续浏览下面的相关文章希望大家以后多多支持自由互联!