zoukankan      html  css  js  c++  java
  • Promise的实现原理

    1.Promise 介绍

      Promise类似一个事务管理器,将用户异步操作流程用流水的形式来表达,用来延迟deferred和异步asynchronous. 特点如下:

     (1)对象的状态不受外界影响

        Promise对象有三种状态

        Pending     进行中

        Resolved   完成状态

        Rejected    失败状态

      只有异步操作的结果,可以决定当前是哪种状态,任何其他操作都无法改变这种状态

     (2)一旦状态改变,就不会再变,任何时候都可以得到这个结果

       状态改变: Pending—> Resolved  /  Pending —> Rejected

       事件的执行一旦错误,再去监听是得不到结果的。

       (3)Promise 对象有两个重要方法,一个是then, 另一个是resolve

      then: 将事务流添加到事务队列中

      resolve:开启流程,让真个流程从第一个事务开始执行

      (4)Promise的常用方式如下:  

    var p = new Promise(function(resolve, reject){
    
        …
    
        //处理事务
    
        resolve()
    
        ….
    
    });
    
    p.then(function(value){
    
        //处理成功
    
    }, function(reason){
    
        //失败处理
    
    }).always(function(){
    
        //总是会执行
    });

     当前Promise是ES6的一个重要特性,JQuery1.8以后也实现了Promise对象.

    2.ES6的Promise

    function helloWorld(flag){
      return new Promise(function(resolve,reject){
            if(flag){
                resolve("Hello World!")
            }else{
                reject("Error")
            }  
        });  
    }  
    
    //helloWord方法返回一个new的Promise对象,Promise回调有两个参数分别处理成功和失败,不想处理的直接传入null即可
    
    helloWorld(true).then(function(message){},function(error){}); 
    helloWorld(true).then(function(message){}); //不处理失败

      每一个then 执行后,又返回一个Promise对象

      Promise.all 可以接收一个元素为 Promise 对象的数组作为参数,当这个数组里面所有的 Promise 对象都变为 resolve 时,该方法才会返回。结果为Promise对象结果集合。

    Promise.all([promise1, promise2]).then(function (result) {
    
          console.log(result); // [“promise1Result”, “promise2result”]
    
    }); 

      不管promise1执行快还是promise2执行快,promise.all会按照数组的吮吸返回结果。

      日常开发中经常会遇到这样的需求,在不同的接口请求数据然后拼合成自己所需的数据,通常这些接口之间没有关联(例如不需要前一个接口的数据作为后一个接口的参数),

    这个时候 Promise.all 方法就可以派上用场了。

    3.JQuery中的Promise实现:

      在jquery1.5之前传统的写法是

    $.ajax({
    
       url:’/ServerResource.txt’,
    
       success: handlerSuccess function,
    
       error: handlerError function
    
    });

    //$.ajax返回一个XHR(XMLHttpRequest)对象,不能进行链式操作

      在jquery1.5之后,$.ajax 会返回$.Deferred对象,新的写法:

    var promise = $.ajax({
      url: "/ServerResource.txt"
    });
     
    promise.done(handlerSuccess);
    promise.fail(handlerError);
    promise.always(alwaysFunction);

      $.ajax() 会返回一个$.Deferred对象,执行完done, fail, always会返回一个新的$.Deferred对象,可以进行链式操作

      promise.done(handlerSuccess).fail(handlerError).always(alwaysFunction)

      $.Deferred对象的好处就是可以任意添加回调函数,就是可以出现多个.done()处理

    promise.done(handlerSuccess1).done(handlerSuccess2).fail(handlerError).always(alwaysFunction) 

      另外一种产生链式调用的方式是利用Promise的 then 方法,它接受三个event handlers作为参数,

      在jquery 1.8之前,对于多个回调函数,有需要以数组方式传入三个参数:  

    $.ajax({url: "/ServerResource.txt"})
    .then([successFunction1, successFunction2, successFunction3], 
        [errorFunction1, errorFunction2]);
     
    //same as
     
    var jqxhr = $.ajax({
      url: "/ServerResource.txt"
    });
     
    jqxhr.done(successFunction1);
    jqxhr.done(successFunction2);
    jqxhr.done(successFunction3);
    jqxhr.fail(errorFunction1);
    jqxhr.fail(errorFunction2); 

      1.8版本之后,then会返回一个新的Promise,它可以通过一个函数过滤掉Deferred对象的状态和值,用于取代不被推荐使用的 defeered.pipe() 方法。

     $.ajax() 返回Promise对象,处理方式和ES6一致。

    var promise = $.ajax({
      url: "/ServerResource.txt"
    });
     
    promise.then(successFunction, errorFunction);
     
    //如果不想处理某个事件类型,可以传入Null
    var promise = $.ajax({
      url: "/ServerResource.txt"
    });
     
    promise.then(successFunction); //no handler for the fail() event
    then()方法还能逐次调用多个方法,可以用于处理有着先后顺序或者依赖的多个Ajax请求:
    
    var promise = $.ajax("/myServerScript1");
     
    function getStuff() {
        return $.ajax("/myServerScript2");
    }
     
    promise.then(getStuff).then(function(myServerScript2Data){  //第一个AJAX的response 作为第二个AJAX的入参
      // Do something 
    });
  • 相关阅读:
    ArcGIS API for JavaScript开发初探——基本地图组件使用
    Win10升级惹的祸,Oracle服务全没有了,怎么解决?
    ArcGIS Pro开发Web3D应用(2)——地图分屏对比(多屏对比)思路
    ArcGIS Pro玩转BIM应用浅谈
    ArcGIS Pro开发Web3D应用(1)——环境搭建与初始实例
    ArcGIS JS API4 With VueJS集成开发
    也谈开源GIS架构实现思想
    Oracle配置SQL空间操作要点说明
    Web直接导入导出SHP/CAD实现探讨。
    ArcGIS Js/Flex等前端API(Query(StatisticDefinition)时)针对SDE的SHAPE.AREA/SHAPE.LEN知道查询无效,而对GDB的SHAPE_Area/SHAPE_Length有效探索。
  • 原文地址:https://www.cnblogs.com/torri/p/6548132.html
Copyright © 2011-2022 走看看