实现一个完美符合Promise/A+规范的Promise

简要介绍:Promise允许我们通过链式调用的方式来解决“回调地狱”的问题,特别是在异步过程中,通过Promise可以保证代码的整洁性和可读性。本文主要解读Promise/A+规范,并在此规范的基础上,自己实现一个Promise.

一、Promise的使用

在了解Promise规范之前,我们知道主流的高版本浏览器已经支持ECMA中的Promise.

创建一个promise实例:

var p=new Promise(function(resolve,reject){
   
    setTimeout(function(){
   
       resolve("success")
    },1000);
    console.log("创建一个新的promise");
})
p.then(function(x){
   
  console.log(x)
})

//输出:
创建一个新的promise
success

上述是一个promise的实例,输出内容为,“创建一个promise”,延迟1000ms后,输出”success”。

从上述的例子可以看出,promise方便处理异步操作。此外promise还可以链式的调用:

var p=new Promise(function(resolve,reject){resolve()});
p.then(...).then(...).then(...)

此外Promise除了then方法外,还提供了Promise.resolve、Promise.all、Promise.race等等方法。

二、Promise/A+规范

Promise/A+规范扩展了早期的Promise/A proposal提案,我们来解读一下Promise/A+规范。

1.术语

(1)”promise”是一个对象或者函数,该对象或者函数有一个then方法

(2)”thenable”是一个对象或者函数,用来定义then方法

(3)”value”是promise状态成功时的值

(4)”reason”是promise状态失败时的值

我们明确术语的目的,是为了在自己实现promise时,保持代码的规范性(也可以跳过此小节)

2.要求

(1)一个promise必须有3个状态,pending,fulfilled(resolved),rejected当处于pending状态的时候,可以转移到fulfilled(resolved)或者rejected状态。当处于fulfilled(resolved)状态或者rejected状态的时候,就不可变。

promise英文译为承诺,也就是说promise的状态一旦发生改变,就永远是不可逆的。

(2)一个promise必须有一个then方法,then方法接受两个参数:

promise.then(onFulfilled,onRejected)

其中onFulfilled方法表示状态从pending——>fulfilled(resolved)时所执行的方法,而onRejected表示状态从pending——>rejected所执行的方法。

(3)为了实现链式调用,then方法必须返回一个promise

promise2=promise1.then(onFulfilled,onRejected)

三、实现一个符合Promise/A+规范的Promise

解读了Promise/A+规范之后,下面我们来看如何实现一个Promise,
首先构造一个myPromise函数,关于所有变量和函数名,应该与规范中保持相同。

1.v1.0 初始版本myPromise

function myPromise(constructor){
   
    let self=this;
    self.status="pending" //定义状态改变前的初始状态
    self.value=undefined;//定义状态为resolved的时候的状态
    self.reason=undefined;//定义状态为rejected的时候的状态
    function resolve(value){
   
        //两个==="pending",保证了状态的改变是不可逆的
       if(self.status==="pending"){
          self.value=value;
          self.status="resolved";
       }
    }
    function reject(reason){
   
        //两个==="pending",保证了状态的改变是不可逆的
       if(self.status==="pending"){
          self.reason=reason;
          self.status="rejected";
       }
    }
    //捕获构造异常
    try{
       constructor(resolve,reject);
    }catch(e){
       reject(e);
    }
}

同时,需要在myPromise的原型上定义链式调用的then方法:

myPromise.prototype.then=function(onFullfilled,onRejected){
   
   let self=this;
   switch(self.status){
      case "resolved":
        onFullfilled(self.value);
        
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值