网站首页  汉语字词  英语词汇  考试资料  写作素材  旧版资料

请输入您要查询的考试资料:

 

标题 javascript Promise简单学习使用方法小结
内容
    下面小编就为大家带来一篇javascript Promise简单学习使用方法小结。小编觉得挺不错的,现在分享给大家,也给大家做个参考。
    解决回调函数嵌套太深,并行逻辑必须串行执行,一个Promise代表一个异步操作的最终结果,跟Promise交互的主要方式是通过他的then()方法来注册回调函数,去接收Promise的最终结果值
    Promise相关的协议有PromiseA和PromiseA+
    定义一个类Promise
    定义属性队列queue,初始化空数组[]
    定义属性值value,初始化null
    定义属性状态status,初始化“pending”(默认值)
    定义成员方法getQueue(),返回属性queue
    定义成员方法getStatus(),返回属性status
    定义成员方法setStatus(),设置状态,传递参数:status,value
    判断status为fulfilled或者rejected,
    设置status属性this.status=status
    设置value属性this.value=value || null ,如果不传value就是null
    定义冻结变量freezeObject
    定义成员方法isFulfilled(),判断当前状态是否是(完成)
    定义成员方法isRejected(),判断当前状态是否是(失败)
    定义成员方法isPending(),判断当前状态师傅是(等待)
    定义成员方法then(),传递参数:onFulfilled成功的回调,onRejected失败的回调
    定义对象handler对象,属性fulfilled,rejected两个回调函数
    定义handler对象的deferred属性,Deferred对象
    判断当前状态是否等待,如果是等待 把handler对象塞入queue队列数组
    如果不是等待状态,调用Utils对象的procedure()方法,参数:status,
    返回 handler.deferred.promise对象
    定义一个类Deferred
    定义属性promise,初始化Promise对象
    定义成员方法resolve(),传递参数:result结果
    判断Promise对象的状态是 等待,直接返回
    调用Promise对象的getQueue()方法,获取queue数组
    循环数组
    //todo调用工具类Utils. procedure()方法,参数:“fulfilled”,元素,err信息
    调用Promise对象的setStatus()方法,设置状态,参数:'fulfilled',result
    定义成员方法reject,传递参数:err错误信息
    判断Promise对象的状态是 等待,直接返回
    调用Promise对象的getQueue()方法,获取queue数组
    循环数组
    //todo,调用工具类Utils. procedure()方法,参数:“rejected”,元素,err信息
    调用Promise对象的setStatus()方法,设置状态,参数:'fulfilled',result
    定义工具类Utils,使用匿名函数立即执行,得到一个对象
    返回对象,对象中有一个方法procedure()
    定义procedure()方法,传递参数:type状态类型,handler处理器数组,result结果
    获取到处理函数func,在handler[type]
    到这里我看晕了。。。
    使用方法:
    定义一个函数ajax,传递参数:url路径
    获取Deferred对象,new出来
    ajax请求数据的代码,在返回数据的回调方法中
    如果成功了调用Deferred对象的resolve()方法,参数:返回的数据
    如果失败了调用Deferred对象的reject()方法,参数:返回的数据
    返回Deferred.promise对象
    调用ajax()方法,得到promise对象,参数:url,
    调用promise对象的then()方法,参数:匿名函数
    调用ajax()方法,获取到promise对象,返回这个对象
    形成链式调用
    js部分:
    <script>
    //Promise代码部分(我选择狗带)
    Promise = function() {
      this.queue = [];
      this.value = null;
      this.status = 'pending';// pending fulfilled rejected
    };
    Promise.prototype.getQueue = function() {
      return this.queue;
    };
    Promise.prototype.getStatus = function() {
      return this.status;
    };
    Promise.prototype.setStatus = function(s, value) {
      if (s === 'fulfilled' || s === 'rejected') {
        this.status = s;
        this.value = value || null;
        this.queue = [];
        var freezeObject = Object.freeze || function(){};
        freezeObject(this);// promise的状态是不可逆的
      } else {
        throw new Error({
          message: "doesn't support status: " + s
        });
      }
    };
    Promise.prototype.isFulfilled = function() {
      return this.status === 'fulfilled';
    };
    Promise.prototype.isRejected = function() {
      return this.status === 'rejected';
    }
    Promise.prototype.isPending = function() {
      return this.status === 'pending';
    }
    Promise.prototype.then = function(onFulfilled, onRejected) {
      var handler = {
        'fulfilled': onFulfilled,
        'rejected': onRejected
      };
      handler.deferred = new Deferred();
      if (!this.isPending()) {//这里允许先改变promise状态后添加回调
        utils.procedure(this.status, handler, this.value);
      } else {
        this.queue.push(handler);//then may be called multiple times on the same promise;规范2.2.6
      }
      return handler.deferred.promise;//then must return a promise;规范2.2.7
    };
    var utils = (function(){
      var makeSignaler = function(deferred, type) {
        return function(result) {
          transition(deferred, type, result);
        }
      };
      var procedure = function(type, handler, result) {
        var func = handler[type];
        var def = handler.deferred;
        if (func) {
          try {
            var newResult = func(result);
            if (newResult && typeof newResult.then === 'function') {//thenable
              // 此种写法存在闭包容易造成内存泄露,我们通过高阶函数解决
              // newResult.then(function(data) {
              //   def.resolve(data);
              // }, function(err) {
              //   def.reject(err);
              // });
              //PromiseA+规范,x代表newResult,promise代表def.promise
              //If x is a promise, adopt its state [3.4]:
              //If x is pending, promise must remain pending until x is fulfilled or rejected.
              //If/when x is fulfilled, fulfill promise with the same value.
              //If/when x is rejected, reject promise with the same reason.
              newResult.then(makeSignaler(def, 'fulfilled'), makeSignaler(def, 'rejected'));//此处的本质是利用了异步闭包
            } else {
              transition(def, type, newResult);
            }
          } catch(err) {
            transition(def, 'rejected', err);
          }
        } else {
          transition(def, type, result);
        }
      };
      var transition = function(deferred, type, result) {
        if (type === 'fulfilled') {
          deferred.resolve(result);
        } else if (type === 'rejected') {
          deferred.reject(result);
        } else if (type !== 'pending') {
          throw new Error({
            'message': "doesn't support type: " + type
          });
        }
      };
      return {
        'procedure': procedure
      }
    })();
    Deferred = function() {
      this.promise = new Promise();
    };
    Deferred.prototype.resolve = function(result) {
      if (!this.promise.isPending()) {
        return;
      }
      var queue = this.promise.getQueue();
      for (var i = 0, len = queue.length; i < len; i++) {
        utils.procedure('fulfilled', queue[i], result);
      }
      this.promise.setStatus('fulfilled', result);
    };
    Deferred.prototype.reject = function(err) {
      if (!this.promise.isPending()) {
        return;
      }
      var queue = this.promise.getQueue();
      for (var i = 0, len = queue.length; i < len; i++) {
        utils.procedure('rejected', queue[i], err);
      }
      this.promise.setStatus('rejected', err);
    }
    /*****************************上面看不懂,分割线************************************/
    //测试部分
    ajax = function(url) {
      var def = new Deferred();
      var xhr = new XMLHttpRequest();
      xhr.onreadystatechange = function() {
        if (xhr.readyState === 4) {
          if ((xhr.status >=200 && xhr.status < 300) || xhr.status === 304) {
            def.resolve(xhr.responseText)
          } else {//简化ajax,没有提供错误回调
            def.reject(new Error({
              message: xhr.status
            }));
          }
        }
      };
      xhr.open('get', url, true);
      xhr.send(null);
      return def.promise;
    }
    ajax('test.php?act=1').then(function(data1) {
      console.log(data1);//处理data1
      return ajax('test.php?act=2');
    }).then(function(data2) {
      console.log(data2);//处理data2
      return ajax('test.php?act=3');
    }, function(err) {
      console.error(err);
    }).then(function(data3) {
      console.log(data3);
      alert('success');
    }, function(err) {
      console.error(err);
    });
    </script>
    php:
    <?php
    if($_GET['act']==1){
      echo json_encode(array("code"=>200));
    }else if($_GET['act']==2){
      echo json_encode(array("code"=>300));
    }else if($_GET['act']==3){
      echo json_encode(array("code"=>400));
    }
    名单
    以上这篇javascript Promise简单学习使用方法小结就是小编分享给大家的全部内容了,希望能给大家一个参考
随便看

 

在线学习网考试资料包含高考、自考、专升本考试、人事考试、公务员考试、大学生村官考试、特岗教师招聘考试、事业单位招聘考试、企业人才招聘、银行招聘、教师招聘、农村信用社招聘、各类资格证书考试等各类考试资料。

 

Copyright © 2002-2024 cuapp.net All Rights Reserved
更新时间:2025/5/18 15:52:17