用Promise处理多个异步Ajax要求致使的代码嵌套题目

题目

前端小同砚在做页面的时刻,犯了个罕见的毛病:把多个Ajax请求递次着写下来了,然后面的请求,对前面请求的返回效果,是有依靠的。以下面的代码所示:

var someData;
$.ajax({
            url: '/prefix/entity1/action1',
            type: 'GET' ,
            async: true,
            contentType: "application/json",
            success: function (resp) {
                //do something on response
               someData.attr1 = resp.attr1;
            },
            error: function (XMLHttpRequest, textStatus, errorThrown) {
                //在这个页面里,一切的请求的毛病都做一样的处置惩罚
                if (XMLHttpRequest.status == "401") {
                    window.location.href = '/login.html';
                } else {
                    alert(XMLHttpRequest.responseText);
                }
            }
        });

$.ajax({
            url: '/prefix/entity2/action2',
            type: 'POST' ,
            dataType: "json",
            data: JSON.stringify(someData),
            async: true,
            contentType: "application/json",
            success: function (resp) {
                //do something on response
             },
            error: function (XMLHttpRequest, textStatus, errorThrown) {
                //在这个页面里,一切的请求的毛病都做一样的处置惩罚
                if (XMLHttpRequest.status == "401") {
                    window.location.href = '/login.html';
                } else {
                    alert(XMLHttpRequest.responseText);
                }
            }
        });

以上代码有两个题目:
*起首就是实行递次不能保证,action2很可能在action1返回之前就发出了,致使someData.attr1这个参数没能准确传出
*其次两个ajax请求的代码反复很严重

思绪

  • 代码反复的题目相对好处理,尤其是在本身的项目里,种种参数能够经由过程范例定死,封装一个参数更少的ajax要领就好了

//url:地点
//data:数据对象,在函数内部会转化成json串,假如没传,示意用GET要领,假如传了,示意用POST要领
function ajax(url, data, callback) {
        $.ajax({
            url: url,
            type: data == null ? 'GET' : 'POST',
            dataType: "json",
            data: data == null ? '' : JSON.stringify(data),
            async: true,
            contentType: "application/json",
            success: function (resp) {
                callback(resp);
            },
            error: function (XMLHttpRequest, textStatus, errorThrown) {
                if (XMLHttpRequest.status == "401") {
                    window.parent.location = '/enterprise/enterprise_login.html';
                    self.location = '/enterprise/enterprise_login.html';
                } else {
                    alert(XMLHttpRequest.responseText);
                }
            }
        });
}

如许只要url,data和callback三个必要的参数要填,其他都定死了

  • 实行递次的题目,能够把第二个请求放在第一个请求的回调里,形如:

ajax('/prefix/entity1/action1',null, function(resp){
     //do something on response
     someData.attr1 = resp.attr1;
     ajax('/prefix/entity2/action2', someData, function(resp){
          //do something on response
     }
};

至此题目好像处理得很圆满,但能够想见,假如请求不止两个,而是4、5个,同时另有其他异步操纵(比方我们的页面里有Vue对象的初始化),相互之间有依靠关联,光是如许层层叠叠的括号嵌套,就已让人头晕了。

须要找到一种要领,让异步挪用的表达看起来像同步挪用一样。

恰好近来看了阮一峰先生关于ES6的书,而且用户也没有倔强请求兼容IE浏览器,于是就挑选了Promise的计划

处理计划

  • 引入Promise
    实在当代浏览器都已内置支撑了Promise,连第三方库都不须要了,只要IE不可,摒弃了

  • 革新ajax封装函数,在胜利的时刻挪用resolve(),失利的时刻挪用reject(),而且返回Promise对象

function ajax(url, data, callback) {
    var p = new Promise(function (resolve, reject) {
        $.ajax({
            url: url,
            type: data == null ? 'GET' : 'POST',
            dataType: "json",
            data: data == null ? '' : JSON.stringify(data),
            async: true,
            contentType: "application/json",
            success: function (resp) {
                callback(resp);
                resolve();
            },
            error: function (XMLHttpRequest, textStatus, errorThrown) {
                if (XMLHttpRequest.status == "401") {
                    window.parent.location = '/enterprise/enterprise_login.html';
                    self.location = '/enterprise/enterprise_login.html';
                } else {
                    alert(XMLHttpRequest.responseText);
                }
                reject();
            }
        });
    });
    return p;
}
  • 修正挪用端

ajax('/prefix/entity1/action1',null, function(resp){
     //do something on response
     someData.attr1 = resp.attr1;
}).then(
     ajax('/prefix/entity2/action2', someData, function(resp){
          //do something on response
     }
).then(
     initVue() ;
).then(
     //do  something else
)

至此圆满处理。

经@miroki 提示,发明Jquery从1.5版最先,返回的就是thenable对象了,那末ajax函数能够直接返回$.ajax()的返回值

    原文作者:songofhawk
    原文地址: https://segmentfault.com/a/1190000008486570
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞