jQuery Deferred进行异步编程

本文详细介绍了jQuery中的Deferred对象及其核心方法,包括done、fail、resolve、reject等,并通过实例展示了如何在实际开发中运用这些方法来处理异步操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


  1. jQuery规定,deferred对象有三种执行状态----未完成,已完成和已失败。如果执行状态是"已完成"(resolved),deferred对象立刻调用done()方法指定的回调函数;如果执行状态是"已失败",调用fail()方法指定的回调函数;如果执行状态是"未完成",则继续等待,或者调用progress()方法指定的回调函数(jQuery1.7版本添加)。

  2. //最佳做法
      var wait = function(){

  3.        var dtd = $.Deferred(); // 内部新建一个deferred对象
        var tasks = function(){
          alert("执行完毕!");
          dtd.resolve(); // 改变deferred对象的执行状态

  4.            //dtd.reject();
        };
        setTimeout(tasks,5000);
        return dtd;
      };

  5. 先介绍两个重要的方法Deferred.done,Deferred.fail

        Deferred.done接收一个函数或者一个函数的数组作为参数,当promise成功返回resolved时触发该方法的执行。

        Deferred.fail接收一个函数或者一个函数的数组作为参数,当promise成功返回rejected时触发该方法的执行

        如果传给$.when的参数不是一个Deferred对象,则$.when将该参数视为一个resolved的Deferred对象,如果没有其他的Deferred对象传入,则触发Deferred.done执行

    例如下面这个例子,fail方法永远不会被触发

  6.   <!DOCTYPE html>
    <html>
    <head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    <script type='text/javascript' src='http://code.jquery.com/jquery-1.7.1.js'></script>
    <script type='text/javascript'>
    //live at jsfiddle.net/Ed5S9
    $(function(){
    function fib() {
    var int1 = 0,
    int2 = 1,
    int3,
    sequence = "<li>0</li><li>1</li>";
    for ( var i = 3; i <= 100; i++ ) {
    int3 = int1 + int2;
    int1 = int2;
    int2 = int3;
    sequence += "<li>"+int3+"</li>"
    }
    $( "#numbers" ).append( sequence ).show( 1000 );
    }
    function success() {
    $( "h1" ).text( "Fibonacci!" );
    }
    function failure() {
    $("h1" ).text( "No numbers?" );
    }
    $(function(){
    $.when( fib() )
    .done( success )
    .fail( failure );
      });
    });
    </script>
    </head>
    <body>
        <div id="main">
            <h1></h1>
            <ul id="numbers" style="display:none">
            </ul>
        </div>
    </body>

    </html>

  7. 正确的写法如下

  8. <!DOCTYPE html>
    <html>
    <head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    <script type='text/javascript' src='http://code.jquery.com/jquery-1.7.1.js'></script>
    <script type='text/javascript'>
    //live at jsfiddle.net/5qAMD
    $(function(){
    function fib() {
    return $.Deferred(function() {
    var int1 = 0,
    int2 = 1,
    int3, sequence = "<li>0</li><li>1</li>";
    for (var i = 3; i <= 100; i++) {
    int3 = int1 + int2;
    int1 = int2;
    int2 = int3;
    sequence += "<li>" + int3 + "</li>"
    }
    $("#numbers")
    .append(sequence)
    .show(1000, this.resolve);
    }).promise();
    }

    function success() {
    $( "h1" ).text( "Fibonacci!" );
    }
    function failure() {
    $ ("h1" ).text( "No numbers?" );
    }
    $(function(){
    $.when( fib() )
    .done( success )
    .fail( failure );
    });

    });

    </script>
    </head>
    <body>
    <div id="main">
        <h1></h1>
        <ul id="numbers" style="display:none">
        </ul>
    </div>
    </body>
    </html>

  9. 相比于$.post(),$.get()于$.ajax()方法,jQuery为Deferred对象提供了一个别名Deferred.then

  10. 第一个参数处理resolved promise情况

  11. 第二个参数处理rejected promise情况

  12. 例如:

  13. $.when(fib())
        .then( success, failure );

  14. 由于Deferred方法是可以链式的,所以Deferred方法可以与.done(),.fail()甚至其他的.then()一起调用

  15. 在ajax中使用Deferred方法,由于在jQuery1.5中使用了Deferred重写了$.ajax(),jqXHR,XMLHttpRequest,所以使其完全具备了Deferred的任何方法

  16. function getStatus() {
        return $.ajax({
             url: "/status/json/",
             dataType: "json" 
          }
        )
    }
    function updateStatus(data) {
        
            var $update = $("<ul />"),
                $statusbar = $("#statusbar"),
                html = "",
                data = data.statusMessages;
            for (var i = 0, test = statusMessages.length; i < test; i++) {
                html += "<li>" + statusMessages[i] + "</li>";
            }
    @@@ same bug as above, don't think data.length is what you want given its binding to data.status. AM@@@
            $update.append(html);
            $statusbar.append($update);
            $statusbar.slideDown(1000);


    }
    $.when(getStatus())
        .done(updateStatus)

  17. 总结:
        (1) $.Deferred() 生成一个deferred对象。
      (2) deferred.done() 指定操作成功时的回调函数
      (3) deferred.fail() 指定操作失败时的回调函数
      (4) deferred.promise() 没有参数时,返回一个新的deferred对象,该对象的运行状态无法被改变;接受参数时,作用为在参数对象上部署deferred接口。
      (5) deferred.resolve([arg]) 手动改变deferred对象的运行状态为"已完成",从而立即触发done()方法。

  18.      **resolve([arg])方法和reject([arg])方法可以接受一个可选参数,该可选参数分别在done()和fail()的执行函数中获取。
      (6)deferred.reject([arg]) 这个方法与deferred.resolve()正好相反,调用后将deferred对象的运行状态变为"已失败",从而立即触发fail()方法。
      (7) $.when() 为多个操作指定回调函数。
      (8)deferred.then()
    如果then()有两个参数,那么第一个参数是done()方法的回调函数,第二个参数是fail()方法的回调方法。如果then()只有一个参数,那么等同于done()。
      (9)deferred.always()
    这个方法也是用来指定回调函数的,它的作用是,不管调用的是deferred.resolve()还是deferred.reject(),最后总是执行。
      $.ajax( "test.html" )
      .always( function() { alert("已执行!");} );

  19.     (10)deferred.state

  20.    放回三个值pending,resovled,rejected分别代表未完成,已完成,失败

  21.     (11)Deferred.progress([arg])和Deferred.notify([arg])跟踪进度   jQuery1.7中新增

  22.     

  23.     <!DOCTYPE html>
    <html>
    <head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    <script type='text/javascript' src='http://code.jquery.com/jquery-1.7.1.js'></script>
    <script type='text/javascript'>
    $(function(){
    var longRunning = function() {
    return $.Deferred(function(dfd) {
    dfd.notify( "operation started" )
    var callback = function() {
    dfd.notify( "operation finished" );
    dfd.resolve();
    }
    setTimeout( callback, 5000 );
    }).promise();
    }
    longRunning().progress(
    function( notification ) {
    $( "#notifier" ).text( notification ).fadeIn( 500 );
    }).done(function() {
    $( "#notifier" ).css({
    "color" : "green",
    "font-weight" : "bold"
    })
    });
    });
    </script>
    </head>
    <body>
    <div id="notifier" style="display:none"></div>
    </body>
    </html>

   

    



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值