jQuery教程之then详解(2)
沉沙 2018-11-16 来源 : 阅读 1052 评论 0

摘要:本篇教程介绍了jQuery教程之then详解(2),希望阅读本篇文章以后大家有所收获,帮助大家对jQuery的理解更加深入。

本篇教程介绍了jQuery教程之then详解(2),希望阅读本篇文章以后大家有所收获,帮助大家对jQuery的理解更加深入。

<

现在我们看下如何利用then()解决第2个问题:如果AJAX请求之间存在依赖关系,我们的代码就会形成Pyramid of Doom(金字塔厄运)。比如我们要完成这样一件事:有4个供Ajax访问的url地址,需要先Ajax访问第1个,在第1个访问完成后,用拿到的返回数据作为参数再访问第2个,第2个访问完成后再第3个...以此到4个全部访问完成。按照这样的写法,似乎会变成这样:
 
[javascript] view plain copy
 
    $.ajax({    
        url: url1,    
        success: function(data){    
            $.ajax({    
                url: url2,    
                data: data,    
                success: function(data){    
                    $.ajax({    
                        //...    
                    });    
                }        
            });    
        }    
    });  
1.Deferred.then()相当于Deferred.done()、Deferred.fail()、Deferred.progress()的合体,可以同时注册3个状态下的回调函数。
[javascript] view plain copy
 
    function success(data)  
    {  
        alert("success data = " + data);  
    }  
      
    function fail(data)  
    {  
        alert("fail data = " + data);  
    }  
      
    function progress(data)  
    {  
        alert("progress data = " + data);  
    }  
      
    var deferred = $.Deferred();  
      
    // 一起注册回调  
    deferred.then(success, fail, progress);  
      
    // 分别注册回调  
    deferred.done(success);  
    deferred.fail(fail);  
    deferred.progress(progress);  
      
    deferred.notify("10%");  
    deferred.resolve("ok");    
当然我们也可以像done()一样,多次调用then()注册回调函数。then()虽然可以这么使用,但是实际开发中一般不这么用,因为没有啥必要。JQuery1.8之前,这就是then()方法的作用。
 
2.Deferred.then()解决多个异步操作之间有依赖的问题,这才是then()真正有意义的场景。JQuery1.8之后,then()取代了过时的pipe()方法。这种场景下,我们需要使用Deferred.then()返回的新Promise对象。上面的第一种使用方式,我们忽略了Deferred.then()的返回值。
 
[javascript] view plain copy
 
    var deferred = $.Deferred();  
      
    // 使用then()注册一个resolved状态的回调函数,并返回一个过滤后的promise  
    // 返回的filtered已经不是原来的Deferred或者Promise对象了  
    var filtered = deferred.then(function( value ) {  
                    alert("trigger Deferred filter.value="+value);//5  
                    return value * 2;  
                });  
      
    // 用过滤后的Promise再次注册回调函数           
    filtered.done(function( value ) {  
        alert("filtered value=" + value);//10  
    });  
       
    deferred.resolve( 5 );  
我们用deferred.then()注册了一个完成状态下的回调函数,这个回调函数得到的值是5;之后用filtered这个新的Promise注册回调函数,这个回调函数中得到的值是10(第一个回调函数的返回结果)。现在我们看下JQuery官方对then的解释:
These filter functions can return a new value to be passed along to the promise's .done() or .fail() callbacks, or they can return another observable object (Deferred, Promise, etc) which will pass its resolved / rejected status and values to the promise's callbacks. If the filter function used is null, or not specified, the promise will be resolved or rejected with the same values as the original.
我们知道deferred.resolve()、deferred.reject()、deferred.notify()可以指定参数值,这个参数会传递给相应状态下的回调函数。如果我们使用的是done()、fail()、progress()注册的回调函数,那么某个状态下的所有回调函数得到的都是相同参数。但是如果我们使用了then()注册回调函数,那么第一回调函数的返回值将作为第二个回调函数的参数,同样的第二个函数的返回值是第三个回调函数的参数。可以对比下面的2段代码,体会下done()和then的差别。
 
[javascript] view plain copy
 
    var deferred = $.Deferred();  
      
    // done()返回的仍然是原来的Deferred对象  
    var done_ret = deferred.done(function(data){  
        alert("data="+data);//5  
        return 2 * data;  
    });  
    alert(deferred == done_ret);//true  
      
    done_ret.done(function(data){  
        alert("data="+data);//5  
    });  
      
    deferred.resolve( 5 );  
 
[javascript] view plain copy
 
    var deferred = $.Deferred();  
      
    // then()返回的是一个新Promise对象  
    //then注册的回调函数的返回值将作为这个新Promise的参数  
    var then_ret = deferred.then(function(data){  
        alert("data="+data);//5  
        return 2 * data;  
    });  
    alert(then_ret == deferred);//false  
      
    then_ret.done(function(data){  
        alert("data="+data);//10  
    });  
      
    deferred.resolve( 5 );  
同样地,Deferred.then也能够实现rejected和pending状态的回调函数过滤。
[javascript] view plain copy
 
    var defer = $.Deferred();  
    var filtered = defer.then( null, function( value ) {  
        return value * 3;  
      });  
       
    defer.reject( 6 );  
      
    filtered.fail(function( value ) {  
      alert( "Value is ( 3*6 = ) 18: " + value );  
    });  
 
 
下面这段代码可以实现chain tasks,解决异步操作中回调难的问题。
 
[javascript] view plain copy
 
    var defered = $.Deferred();  
      
    var promise1 = defered.then(function(data){  
        alert(data);//  
        return data+="1";  
    });  
      
    var promise2 = promise1.then(function(data){  
        alert(data);//1  
        return data+="2";  
    });  
      
    var promise3 = promise2.then(function(data){  
        alert(data);//12  
        return data+="3";  
    });  
      
    promise3.done(function(data){  
        alert(data);//123  
    });  
      
    defered.resolve("");  
 
 
正是由于then()这个特性,我们就可以上面复杂的AJAX嵌套改成如下形式:
[javascript] view plain copy
 
        var promise1 = $.ajax(url1);  
        var promise2 = promise1.then(function(data){  
            return $.ajax(url2, { "data": data });  
        });  
        var promise3 = promise2.then(function(data){  
            return $.ajax(url3, { "data": data });  
        });  
        promise3.done(function(data){  
            // data retrieved from url3  
        });  
   

本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标WEB前端jQuery频道!

本文由 @沉沙 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程