做有态度的前端团队

网易FEG前端团队

初探关于ajax多个请求,但需要全部完成后才能执行的方法

本文主要总结一下需要等待多个ajax请求完成后再执行操作的方法

最近在做一个英雄榜项目遇到一个问题,需要用到6次Ajax来获取各个榜单的数据再进行操作。

一、ajax嵌套ajax,传说中的嵌套金字塔,以及这种方式只能串联发起ajax请求

    function getDataFun(){
        $.ajax({url: "/equip_rank",type:'GET',dataType:'jsonp',success: function(data1){
                $.ajax({url: "/score_rank",type:'GET',dataType:'jsonp',success: function(data2){
                        $.ajax({url: "/summon_rank",type:'GET',dataType:'jsonp',success: function(data3){
                                console.log(data1);
                                console.log(data2);
                                console.log(data3);
    
                            }
                        })
                    }
                })
            }
        })
    }

以上方法虽然可行,但是当ajax请求增多,嵌套层数也逐渐加深,代码就变得难以维护了,而且请求是串联发起的,效率也不高。

二、设置一个全局变量flag,所有ajax接口都可以同时发起请求,而且代码分离,在每个ajax的回调中都统一回调一个函数,由这个函数来判断flag值是否达到条件。

    function getDataFun(){
        var flag = 0,
            _data1,
            _data2,
            _data3;
        $.ajax({url: "/equip_rank",type:'GET',dataType:'jsonp',success: function(data1){
                flag++;
                _data1 = data1;
                if(flag == 3){
                    //do something
                }
            }
        })
    
        $.ajax({url: "/score_rank",type:'GET',dataType:'jsonp',success: function(data2){
                flag++;
                _data2 = data2;
    
                if(flag == 3){
                    //do something
                }
            }
        })
    
        $.ajax({url: "/billionaire_rank",type:'GET',dataType:'jsonp',success: function(data3){
                flag++;
                _data3 = data3;
    
                if(flag == 3){
                    //do something
                }
            }
        })
    }

三、使用jquery的$.when()方法,就是promise模式,让异步请求方式变为链式调用,以及能做到并联请求

jquery的ajax方法返回的对象Deferred Object,因此可以用$.when()处理返回的结果。使用$.when()方法,多个异步请求是同步处理的,而且它返回的是promise对象,可以使用then,done来处理返回的结果。

    function getDataFun(){
        var fun1 = $.ajax({url: "/equip_rank",type:'GET',dataType:'jsonp'}),
            fun2 = $.ajax({url: "/score_rank",type:'GET',dataType:'jsonp'}),
            fun3 = $.ajax({url: "/billionaire_rank",type:'GET',dataType:'jsonp'});
        $.when(fun1,fun2,fun3).then(function(data1,data2,data3){
            //成功回调,所有请求正确返回时调用
            console.log(data1[0]);
            console.log(data2);
            console.log(data3);
        },function(){
            //失败回调,任意一个请求失败时返回
            console.log('fail!!');
        })  
    }

如果所有请求成功返回,then方法里面的第一个回调执行,如果任意一个请求失败,则执行then方法里面的第二个回调。注意每个请求返回的结果,例如本例中的data1,data2,data3实际上返回的是一个数组,里面的数据依次是[data,statusText,jqXHR]。

此处还有一种情况就是,如果请求个数不确定怎么破,我们可以用js里面的apply方法,把请求放在数组里面处理。

    function getDataFun(){
        var reqlist = [];
        reqlist.push($.ajax({url: "/equip_rank",type:'GET',dataType:'jsonp'}));
        reqlist.push($.ajax({url: "/score_rank",type:'GET',dataType:'jsonp'}));
        reqlist.push($.ajax({url: "/billionaire_rank",type:'GET',dataType:'jsonp'}));
    
        $.when.apply($,reqlist).then(function(data1,data2,data3){
            //成功回调,所有请求正确返回时调用
            console.log(data1[0]);
            console.log(data2[1]);
            console.log(data3[2]);
        },function(){
            //失败回调,任意一个请求失败时返回
            console.log('fail!!');
        })
    }

四、让后台把请求合并成一个

注意:
ajax为异步请求,绝对不能使用setTimeout方式做回调,因为setTimeout会因用户的网速,服务器响应时间,电脑配置等问题,会导致异步时间不一样。

webwxgetmsgimg.jpg

手机阅读请扫描下方二维码:

none
上一篇:图片懒加载   下一篇:小白带你探索WebP

已有 2 条评论

  1. 这么好的文 没人评论?还有王法么 还有法律么 ali-43.gif ali-59.gif

  2. 1

    1

添加新评论

ali-40.gifali-41.gifali-42.gifali-43.gifali-44.gifali-45.gifali-46.gifali-47.gifali-48.gifali-49.gifali-50.gifali-51.gifali-52.gifali-53.gifali-54.gifali-55.gifali-56.gifali-57.gifali-58.gifali-59.gifali-60.gifali-61.gif