问题

前端小同学在做页面的时候,犯了个常见的错误:把多个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()的返回值

本文转自:https://segmentfault.com/a/1190000008486570

用Promise解决多个异步Ajax请求导致的代码嵌套问题【转】的更多相关文章

  1. Ajax引擎:ajax请求步骤详细代码

    说起AJAX,可能是很多同学在很多地方都看到过,各大招聘网站上对于WEB前端和PHP程序员的技能要求清单中也是必不可少的一项.但是,ajax请求步骤详细代码以及说明却比较少见到 什么是AJAX引擎? ...

  2. 解决拦截器对ajax请求的的拦截

    拦截器配置: public boolean preHandle(HttpServletRequest request, HttpServletResponse response,Object obj) ...

  3. 异步ajax请求数据处理

    jQuery.ajax(url,[settings]) 概述 通过 HTTP 请求加载远程数据. jQuery 底层 AJAX 实现.简单易用的高层实现见 $.get, $.post 等.$.ajax ...

  4. 多个异步ajax请求指定顺序执行

    1.比如2个ajax请求,把第二个ajax请求放在第一个ajax请求success方法里面. 2.ajax请求时添加 async: false,//使用同步的方式,true为异步方式.结果是只有等服务 ...

  5. 解决spring-security session超时 Ajax 请求没有重定向的问题

    开始时, 代码是这样的: $.ajax({ type : "POST", url : sSource, cache : false, dataType : "json&q ...

  6. 【django基础】django接口 异步ajax请求 导出数据库成excel表(包裹前端后端)

    py文件: from django.utils.http import urlquote from rest_framework.views import APIView from django.sh ...

  7. springboot+shiro 02 - 异步ajax请求无权限时,返回json格式数据

    博客: https://www.cnblogs.com/youxiu326/p/shiro-01.html github:https://github.com/youxiu326/sb_shiro_s ...

  8. ajax请求, 前后端, 代码示例

    [博客园cnblogs笔者m-yb原创,转载请加本文博客链接,笔者github: https://github.com/mayangbo666,公众号aandb7,QQ群927113708] http ...

  9. ajax请求导致status为canceled(无任何回调数据)的原因

    1.故障现象 一个普通的ajax请求,请求能够到达controller,也能正常处理业务,但是ajax的回调函数为空,即没有任何状态和数据返回,使用谷歌浏览器查看请求状态如下图: 出现该错误:简单来说 ...

随机推荐

  1. leetcode — substring-with-concatenation-of-all-words

    import java.util.*; /** * Source : https://oj.leetcode.com/problems/substring-with-concatenation-of- ...

  2. 函数调用的区别:_cdecl以及_stdcall

    一.概念1)_stdcall调用   _stdcall是Pascal程序的缺省调用方式,参数采用从右到左的压栈方式,由调用者完成压栈操作,被调函数自身在返回前清空堆栈.   WIN32 Api都采用_ ...

  3. 使用Scratch进行少儿编程

    在上一篇<初识少儿编程>曾提到过Scratch的脚本标签内包含10大模块,本文将围绕这10大模块展开,分为两部分:积木和编程概念,结合<动手玩转Scratch2.0编程―STEAM创 ...

  4. 【awesome-dotnet-core-learning】(3)-Bogus-假数据生成器

    [awesome-dotnet-core-learning](3)-Bogus-假数据生成器 简介 Bogus一个简单而强大的假数据生成器,用于C#,F#和VB.NET.从著名的faker.js移植过 ...

  5. 深度学习论文翻译解析(二):An End-to-End Trainable Neural Network for Image-based Sequence Recognition and Its Application to Scene Text Recognition

    论文标题:An End-to-End Trainable Neural Network for Image-based Sequence Recognition and Its Application ...

  6. U3D Transform用法

    最近在学习unity3d,下面对Transform类做一个小结 一.常用属性和方法 1.1 常用属性: 用代码展示一下上面的一些属性,值得注意的是myCube是mySphere的父物体 using U ...

  7. c#:HttpClient加标头

    using (var client = new HttpClient()) { string requestUrl = string.Format("{0}{1}", ConstD ...

  8. Linux常用基本命令:三剑客命令之-awk格式化动作

    我们之前说过,awk是一个超强的文本格式化工具,而本文的printf动作就是经常用来做格式化文本的.使用方式跟c语言的printf差不多. 1,printf默认不会回车换行 ghostwu@dev:~ ...

  9. 原生JS强大DOM选择器querySelector与querySelectorAll

    在传统的 JavaScript 开发中,查找 DOM 往往是开发人员遇到的第一个头疼的问题,原生的 JavaScript 所提供的 DOM 选择方法并不多,仅仅局限于通过 tag, name, id ...

  10. H5新标签(适合新手入门)

    H5新标签 文档类型设定 document HTML: sublime 输入 html:4s XHTML: sublime 输入 html:xt HTML5 sublime 输入 html:5 < ...