zoukankan      html  css  js  c++  java
  • 手写Promise简易版

    话不多说,直接上代码

    通过ES5的模块化封装,向外暴露一个属性

    (function(window){

      const PENDING = 'pending';

      const RESOLVED = 'fulfilled'

      const REJECTED = 'rejected'

      function MyPromise(excutor){

        const self = this;   //保存Promise对象,防止异步执行时,拿不到数据和方法,必要

        self.value = undefined;

        self.status = PENDING;

        self.callbacks = [] //当状态没有发生改变时,需要储存起回调函数, 在then方法中获取回调函数

        function resolve(value){

          self.value = value;

          self.status = RESOLVED;

          self.callbacks.map(cb => {

            setTimeout(() => { //定时器模拟异步执行,必须保证回调异步执行,否则顺序就乱了

               cb.onResolved(self.value)

            })

          }) //执行保存起来的成功回调函数

        }

         function reject(value){

          self.value = value;

          self.status = REJECTED ; 

          self.callbacks.map(cb => {

            setTimeout(() => {

              cb.onRejected (self.value)

            })

          })//执行保存起来的失败的回调函数

        }

        try{   //若在执行器函数中主动抛出错误,需要捕获错误,并把状态更改为rejected

          excutor(resolve,reject)

        } catch (error){

          reject(error)

        }

      }

      MyPromise.prototype.then = function( onResolved,onRejected ){

        const self = this//保存当前的Promise对象

        return new Promise(resolve,reject){

          onResolved = onResolved === 'function' ? onResolved : v => v

          onRejected  = onRejected === 'function' ? onRejected :  error => {throw error}  //实现异常透传

          //判断当前的状态

          //假如Promise执行的异步任务,then方法是同步方法,那么当时Promise的状态为pending,所以不能执行回调,此时需要保存

          if(self.status === PENDING){

            // 这里只是把回调保存了起来,并没有改变当前的Promise对象,所以得进一步处理,处理和成功得处理类似

            self.callbacks.push({onResolved,onRejected})  //保存每一个then方法为一个对象,包含onResolved,onRejected两个函数

          } else if(self.status === RESOLVED){

            //1. 保证then中的回调异步执行,加一个setTimeout

            //2. 在onResolved中如果主动抛出错误,需要捕获错误

            //3. 根据Promise对象返回的结果,来决定下一个then中执行成功还是失败的回调

            //4. 如果上一个Promise返回的是一个值,如return 2,那么直接用resolve(2)执行

            //5. 如果上一个Promise返回的是一个promise对象,那么要通过promise.then 来获取promise的执行结果

            setTimeout(() => {

              try { 

                 const result = onResolved(self.value)

                if( result instanceof MyPromise){ //判断返回值是不是Promise对象

                  //返回一个Promise对象

                  result.then( 

                    value => {  //返回值是Promise对象,并且是成功的,那么就会执行这一个函数

                      resolve(self.value)

                    }  

                    error => {  //返回值是Promise对象,并且是失败的,那么就会执行这一个函数

                      rejecte(self.value)

                    }

                  )  

                }else {  //返回的不是一个Promise对象

                   resolve(self.value)

                }

              } catch (error) {

                 //与成功的处理一样,只需要更改一下回调函数,太长就不写了

              }

            })

          } else { //rejected状态}  

          }

        }

      window.MyPromise = MyPromise //向外暴露方法

    })(window)

    到这里就差不多写完简易的promise了,了解了原理也能更好的使用promise

    欢迎指正,若有不清楚,也可评论指出

  • 相关阅读:
    使用KRPano资源分析工具一键下载全景网站切片图
    使用KRPano资源分析工具解密被加密的XML
    数据库---表---增删改与权限
    数据库---表---表操作练习
    数据库---表---完整性约束
    数据库---表---数据类型
    数据库---表操作---增删改查
    数据库---库操作---表操作
    数据库---初识sql语句
    数据库---mysql的介绍和安装
  • 原文地址:https://www.cnblogs.com/vnwith/p/12600643.html
Copyright © 2011-2022 走看看