JavaScript之Promise实现

简介: 自己动手写Promise

ES2015提出了Promise,同时基于Promise的异步开发将开发者中回调地狱中解救出来。但在没有原生支持的环境下,需要借助Promise/A+之类的库来实现Promise,今天就来尝试自行实现Promise。

1 基本实现

首先来完成一个Promise类的基本框架:

function Promise(fn) {
  var resolveCallback = null
  var rejectCallback = null
  
  this.then = function(onResolved, onRejected) {
      resolveCallback = onResolved
      rejectCallback = onRejected
  }
  
  this.resolve = function(value) {
      this.resolveCallback(value)
  }
  
  this.reject = function(reason) {
      this.rejectCallback(reason)
  }
  
  fn(this.resolve, this.reject)
}

以上便是Promise的基本实现。

2 状态管理

上述的代码存在一个问题,resolve方法会调用多次,所以接下来我们需要接入状态管理。

Promise内部存在3个状态:

  • pending
  • resolved
  • rejected

接下来在现有代码之上,加入状态管理:

function MyPromise(fn) {
  let state = 'pending'
  var resolveCallback = null
  var rejectCallback = null
  var childResolve
  var childReject
  
  this.then = function(onResolved, onRejected) {
      resolveCallback = onResolved
      rejectCallback = onRejected
  }
  
  this.resolve = function(value) {
      if(state === 'pending') {
         this.resolveCallback(value)
         state = 'resolved' 
      } 
  }
  
  this.reject = function(reason) {
      if(state === 'pending') {
          this.rejectCallback(reason)
          state = 'rejected'
      }   
  }
  
  fn(this.resolve, this.reject)
}

3 链式调用

上述Promise实现可以完成正常的异步调用,但是却无法实现链式回调,原因在于其then方法没有返回一个新的Promise对象,所以接下来还需要改造then方法,实现链式调用:

  this.then = function(onResolved, onRejected) {
      if(state === 'pending') {
          resolveCallback = onResolved
          rejectCallback = onRejected
      }
    
      return new MyPromise((resolve, reject) => {
        ......
      })
  }

光返回一个promise对象还没用,接下来我们来写个demo测试下:

  var demo = new MyPromise((resolve, reject) => {
      setTimeout(() => {
          resolve('my first promise')
      }, 1000)
  })

  demo.then((msg) => {
      console.log(msg)
      return 'my second promise'
  }).then((msg) => {
      console.log(msg)
  })

其输出为:

my first promise

事实上,第二个promise对象的resolve reject方法从未被调用过,因而其onResolved onRejected的回调ye就无从调用。所以还必须指定时机调用字promise对象的resolvereject

所以首先需要在创建新promise对象时,记录其resolvereject方法:

function MyPromise() {
    ......
    var childResolve
    var childReject
    
      this.then = function(onResolved, onRejected) {
      if(state === 'pending') {
          resolveCallback = onResolved
          rejectCallback = onRejected
      }
    
      return new MyPromise((resolve, reject) => {
        childResolve = resolve
        childReject = reject
      })
  }
}

接下来还需在resolvereject方法中调用子对象的resolvereject方法,整个Promise完整代码如下:

function MyPromise(fn) {
    let state = 'pending'
    var resolveCallback = null
    var rejectCallback = null
    var childResolve = null
    var childReject = null
    
    this.then = function(onResolved, onRejected) {
        if(state === 'pending') {
            resolveCallback = onResolved
            rejectCallback = onRejected
        }
      
        return new MyPromise((resolve, reject) => {
            childResolve = resolve
            childReject = reject
        })
    }
    
    this.resolve = function(value) {
        if(state === 'pending') {
            if(resolveCallback) {
                var ret = resolveCallback(value)
                childResolve(ret)
                state = 'resolved' 
            }

        } 
    }
    
    this.reject = function(reason) {
        if(state === 'pending') {
            if(rejectCallback) {
                var ret = rejectCallback(reason)
                childReject(ret)
                state = 'rejected'
            }
        }   
    }
    
    fn(this.resolve, this.reject)
  }
相关文章
|
30天前
|
前端开发 JavaScript
JavaScript——promise 是解决异步问题的方法嘛
JavaScript——promise 是解决异步问题的方法嘛
30 0
|
1月前
|
前端开发 JavaScript API
JavaScript 中的 Promise
Promise 是 JavaScript 中用于处理异步操作的一种模式,它提供了一种比传统的回调函数更清晰、更易于管理和控制的方式来处理异步流程。
|
27天前
|
设计模式 前端开发 JavaScript
javascript 异常问题之Promise的未处理异常如何捕获
javascript 异常问题之Promise的未处理异常如何捕获
|
27天前
|
监控 前端开发 JavaScript
javascript 异常问题之在JavaScript中,Promise的异常如何处理
javascript 异常问题之在JavaScript中,Promise的异常如何处理
|
27天前
|
前端开发 JavaScript
javascript 异常问题之Promise异常如何捕获
javascript 异常问题之Promise异常如何捕获
|
29天前
|
前端开发 JavaScript
JavaScript异步编程4——Promise错误处理
JavaScript异步编程4——Promise错误处理
33 0
|
29天前
|
存储 JSON 前端开发
JavaScript异步编程3——Promise的链式使用
JavaScript异步编程3——Promise的链式使用
20 0
|
29天前
|
前端开发 JavaScript API
JavaScript异步编程2——结合XMLHttpRequest使用Promise
JavaScript异步编程2——结合XMLHttpRequest使用Promise
14 0
|
29天前
|
前端开发 JavaScript
JavaScript异步编程1——Promise的初步使用
JavaScript异步编程1——Promise的初步使用
22 0
|
2月前
|
前端开发 JavaScript
JavaScript异步编程:Promise与async/await的深入探索
【7月更文挑战第9天】Promise和async/await是JavaScript中处理异步编程的两大利器。Promise为异步操作提供了统一的接口和链式调用的能力,而async/await则在此基础上进一步简化了异步代码的书写和阅读。掌握它们,将使我们能够更加高效地编写出清晰、健壮的异步JavaScript代码。

热门文章

最新文章