Promise/A+原理与实现

1. promise 状态

一个 Promise 的当前状态必须为以下三种状态中的一种:等待态(Pending)、执行态(Fulfilled)和拒绝态(Rejected),状态改变只能是 pending 到 fulfilled 或者 pending 到 rejected 。状态改变不可逆。

  • Pending ----处于等待态时,promise 需满足的条件:可以迁移至执行态或拒绝态
  • Fulfilled -----处于执行态时,promise 需满足的条件:不能迁移至其他任何状态,必须拥 有一个不可变的终值
  • Rejected----处于拒绝态时,promise 需满足的条件:不能迁移至其他任何状态,必须拥有一个不可变的据因

2. Then 方法

一个 promise 必须提供一个 then 方法以访问其当前值终值据因

promise 的 then 方法接受两个参数:

promise.then(onFulfilled, onRejected)

onFulfilled 和 onRejected 都是可选参数。如果 onFulfilled ,onRejected不是函数,其必须被忽略。
then 方法可以被同一个 promise 调用多次

  • 当 promise 成功执行时,所有 onFulfilled 需按照其注册顺序依次回调
  • 当 promise 被拒绝执行时,所有的 onRejected 需按照其注册顺序依次回调

按照标准实现 promise

1.创建一个最基本的 promise

首先创建一个 promise
promise 构造函数中接受一个 executor 函数
executor函数中接收了两个函数,一个是成功回调的函数,第二个是失败回调的函数,代码如下:

class Promise{
    constructor(executor){
        //参数校验
        if(typeof executor !== 'function'){ //如果传进来的 executor 不是一个函数 抛出相应的异常
            throw new Error(`TypeError: Promise resolver ${executor} is not a function`)
        }
        const resolve = (value)=>{
            //成功后的操作(成功的回调的执行)
        }
        const reject = (reason)=>{
            //失败后的操作(失败的回调的执行)
        }
        //捕获异常
        try{
            executor(resolve,reject)
        }catch(err){
            reject(err)
        }
    }
}
module.exports=Promise
  1. 设置value(成功执行返回的value)、reason(执行失败的拒因) ,和state(执行状态的初始值),并在 resolve 和 reject 函数中实现相应的操作:
class Promise{
    constructor(executor){
        //参数校验
        if(typeof executor !== 'function'){ //如果传进来的 executor 不是一个函数 抛出相应的异常
            throw new Error(`TypeError: Promise resolver ${executor} is not a function`)
        }

        //初始值
+        this.value = null;//成功返回的值
+        this.reason = null;//失败返回的值
+        this.state = 'pending';//状态值,初始值为pending

        const resolve = (value)=>{
            //成功后的操作(成功的回调的执行)
+            if(this.state === 'pending'){
+                //变为成功的状态
+                this.state='fulfilled'
+                this.value = value //将成功的结果赋值给value
+            }
        }
        const reject = (reason)=>{
            //失败后的操作(失败的回调的执行)
+            if(this.state === 'pending'){
+                //状态变为失败的状态
+                this.state='rejected'
+                this.reason = reason;//将成功的结果赋值给reason
+            }
        }
        //捕获异常
        try{
            executor(resolve,reject)
        }catch(err){
            reject(err)
        }
    }
}
module.exports=Promise
2.实现then方法

then方法的实现遵循的规则:promise.then(onFulfilled, onRejected)
它接受了两个参数 onFulfilled 和 onRejected

executor自执行函数中的resolve参数调用时执行then方法的第一个回调函数onFulfilled
executor自执行函数中的reject参数调用时执行then方法的第二个回调函数onRejected
then方法返回一个新的promise对象

onFulfilled 和 onRejected 必须是一个函数,如果onFulfilled不是函数,直接将值返回,如果onRejected不是函数,将reason抛出

 //then方法的实现
 then(onFulfilled,onRejected){
        //如果onFulfilled不是函数,直接将值返回
        if(typeof onFulfilled !== 'function'){
            onFulfilled = function(value){
                return  value
            }
        }
        //如果onRejected不是函数,将reason抛出
        if(typeof onRejected !== 'function'){
            onRejected=function(reason){
                throw reason
            }
        }

        
        //判断目前所处的状态
        if(this.state === 'fulfilled'){
            //成功
            onFulfilled(this.value)
        }
        if(this.state === 'rejected'){
            //失败
            onRejected(this.reason)
        }
   }

此时已经完成了then方法的初步封装,接下来对then方法的不足进行一步步改善;
测试:

const Promise = require('./promise') 


console.log(1)
new Promise((resolve,reject)=>{
    console.log(2)
  	resolve(“nihao”)
})
.then(value=>{
    console.log(4)
    console.log("value",value)
},reason=>{
    console.log("reason",reason)
})
console.log(3)

我们会发现我们写的代码的打印顺序是,1,2,4,3,正常引入的 promise,正确的打印顺序应该是1,2,3,4,为什么打印 4 的时候没用进行等待直接就打印了呢?

原因: 我们在then方法中对 onFulfilled 和 onRejected 没有进行异步操作,直接执行的的这两个方法,下面我们用定时器对两个方法进行异步操作:
异步解决:

 then(onFulfilled,onRejected){
        //如果onFulfilled不是函数,直接将值返回
        if(typeof onFulfilled !== 'function'){
            onFulfilled = function(value){
                return  value
            }
        }
        //如果onRejected不是函数,将reason抛出
        if(typeof onRejected !== 'function'){
            onRejected=function(reason){
                throw reason
            }
        }
        //判断目前所处的状态
        if(this.state === 'fulfilled'){
            //成功
+            setTimeout(()=>{//异步的实现解决
                onFulfilled(this.value)
+            })
        }
        if(this.state === 'rejected'){
            //失败
+            setTimeout(()=>{//异步的实现解决
                onRejected(this.reason)
+            })
        }
   }

3. 实现链式调用,

正在学习,后续更新。。

猜你喜欢

转载自blog.csdn.net/weixin_48786946/article/details/106888790
今日推荐