jquery 的 promise编程

来源:互联网 发布:国际大数据大会 华云 编辑:程序博客网 时间:2024/06/15 09:08

1、为什么会有promise

这里我不阐述什么特别详细的概念,直接以实际需求出发。

现在手上的问题是,前端需要用echarts构建一个图表,而数据是通过ajax请求rest的数据接口而来的,但是echarts绘图需要的数据需要同时请求到多个数据源,

才能完整的将图表画出来。常规的写法是,JavaScript的函数回调,也就是下面的代码:

ajax 函数回调:

<!DOCTYPE html><html lang="en"><head>  <meta charset="UTF-8">  <title>ajax 回调形式</title></head><body></body><script src="../../../vender/jquery.js"></script><script>  $.ajax({    type: "GET",    url: "rest1",    success: function(res){      //接口rest1 的数据请求成功,接着去请求rest2 的数据      var rest1Data = res;      $.ajax({        type: "GET",        url: "rest2",        success: function(res){          var rest2Data = res;                    //使用数据rest1Data 和 rest2Data 绘图表          drawGraph(rest1Data,rest2Data);        }      });    }  });</script></html>

看了上面的代码就给人一种想吐的冲动,不说写起来繁杂,而且还没技术含量,总之就是不上档次,而且现在是两个数据源,如果是多个数据源难道要一直的嵌套下去?

没办法,为了装逼,我不得不开始骚扰度娘。。。于是我找到了commonjs提出的promise 编程理念,瞬间感觉世界有爱了,有木有?!


2.什么是promise

promise编程,个人理解就是,同步编程,异步执行。通过一个deferred延迟对象,帮我们搞定所有的事情,你敢信?哈哈,不得不信啊。。。

关于promise一些基础概念,自行百度下吧,骚年,下面我直接使用jQuery的promise来实现,上代码:


$.ajax("rest1").done(function (res) {    var res1Data = res;
    //请求rest2的数据<span style="white-space:pre"></span>    $.ajax("rest1").done(function (res) {      var res2Data = res;            //绘图表      drawGraph(res1Data,res2Data)    })  })    .fail(function () {      alert("出错啦!");    })    .done(function () {      alert("第二个回调函数!");    });

如果你在这段时间已经看了jquery的延迟对象相关的概念,肯定会发现还有$.when()这个牛逼的方法,所以我们的代码可以改写成如下方式:

$.when($.ajax("rest1"), $.ajax("rest2"))          .done(function(v1,v2){            var rest1Data = v1[0].data;            var rest2Data = v1[1].data;                        //绘图表            drawGraph();          })          .fail(function(){ alert("出错啦!"); });

解释一些吧:

$.when() 的方法参数 为 延迟对象,可以为多个,$.ajax() 方法调用后返回的即是一个promise对象,ajax调用后对应返回的数据,封装到done方法的回调函数中的参数中,也就是时上述的v1,v2对象。


3.promise的进阶

上述说了半天只是为了解决我实际遇到的问题,但有时候我们需要的不是ajax的请求,而是普通的函数回调,有点绕啊,没事,我举例子,呵呵!

加入说我们声明了一个回调函数,这个函数很耗时,比如:

 var wait = function(){    var tasks = function(){      alert("执行完毕!");    };    setTimeout(tasks,5000);  };


我们为这个函数指定回调该怎么执行呢?我们可以这么写。。。

 var dtd = $.Deferred(); // 生成Deferred对象  var wait = function(dtd){    var tasks = function(){      alert("执行完毕!");      dtd.resolve(); // 改变Deferred对象的执行状态    };    setTimeout(tasks,5000);  };  dtd.promise(wait);  wait.done(function(){ alert("哈哈,成功了!"); })          .fail(function(){ alert("出错啦!"); });  wait(dtd);


解释一些吧:

1、首先声明一个defferd对象,

2、在声明wait()函数时,虽然很耗时,但我们在函数执行完时,通过deferred对象返回一个promise对象,

3、接下来,我们就可以调用jQuery给我们提供的关于pomise的一系列API了


4.jQuery中的defered的一些API总结:

(1) $.Deferred() 生成一个deferred对象

(2) deferred.done() 指定操作成功时的回调函数

(3) deferred.fail() 指定操作失败的回调韩式

(4) deferred.promise() 没有参数时,返回一个新的deferred对象,该对象的运行状态无法改变:接受参数时,作用为在参数对象上部署到deffered接口上

(5) deferred.resolve() 手动改变deffered对象的运行状态“已完成”,从而触发done()方法

(6) deferred.reject() 这个方法与deffered.resolve()正好相反,调用后将deffered对象的运行状态改变为“已失败”,从而立即触发fail()方法

(7) $.when() 为多个操作指定回调函数,参数为多个deffered对象

(8) deferred.then() 可以整合done()和fail()

$.when($.ajax('rest')).then(successFunc, failFunc);

        (9) deferred.always()  这个方法也是用来指定回调函数的,它的作用是,不管调用的是deferred.resolve()还是deferred.reject(),最后总是执行。
  $.ajax( "test.html" ).always( function() { alert("已执行!");} );



5.最后的最后。。。

写到这,也算是解决问题了,不过笔者已有未尽,最后和大家聊聊现在比较火的angular中promise实现,主要是$q, 这个服务,算了,不聊了,还是直接上代码

 var q1 = $.get('rest1');  var q2 = $.get('rest2');    $q.all([q1,q2]).then(function(res){    var res1Data = res[0].data;    var res2Data = res[0].data;        //绘图表    drawGraph();  });



 






0 0
原创粉丝点击