问题

前端小同学在做页面的时候,犯了个常见的错误:把多个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. 进程间通信IPC-管道

    管道是UNIX系统IPC的最古老的形式,所有的UNIX系统都提供此通讯机制.管道有以下两种局限性: 1, 历史上,它们是半双工的(即数据只能在一个方向上流动).现在某些系统提供了全双工管道,但是为了最 ...

  2. jobss目录结构

    一. JBoss的目录结构       bin:包含各种脚本文件以及相关文件,比如run.bat和shutdown.bat批处理文件.        client:存储配置信息和可能被Java客户端应 ...

  3. JavaWeb学习(一)———JavaWeb入门

    一.基本概念 1.1.WEB开发的相关知识 WEB,在英语中web即表示网页的意思,它用于表示Internet主机上供外界访问的资源. Internet上供外界访问的Web资源分为: 静态web资源( ...

  4. js获取带#号链接后的参数

    现在许多的主流网站都将'#'大规模用于重要URL中,我们通过正则表达式和window.location.search获取参数已经行不通了. 一.'#'号是什么 1.#代表网页中的一个位置.其后面的字符 ...

  5. Linux IPC基础(System V)

    简介 IPC 主要有消息队列.信号量和共享内存3种机制.和文件一样,IPC 在使用前必须先创建,使用 ipcs 命令可以查看当前系统正在使用的 IPC 工具: 由以上可以看出,一个 IPC 至少包含 ...

  6. MVC 【Razor 视图引擎】基础操作 --页面跳转,传值,表单提交

    ASPX  与  Razor  仅仅是视图不一样. 新建项目----ASP.NET MVC 4 Web 应用程序------选择模板(空).视图引擎(Razor ) 1.视图中 c# 代码  与 HT ...

  7. 【Core】创建简单的Core MVC项目

    创建项目: 首先:打开vs选中新建项目- >选中.NET Core - >ASP.NET Core Web应用程序: 然后:在选择web应用程序,注意上面要选中.net Core 别选错了 ...

  8. Java 面向对象编程小练习(曾经)

    最近打算将之前学习过的小练习分享出来,算是巩固知识.虽然是小练习,但是越看越觉得有趣,温故而知新. 练习:功能跳水比赛,8个评委评分.运动员成绩去掉最高和最低之后的平均分 代码实例: 1.导包 imp ...

  9. 【协议】1、tcp,http,socket协议介绍

    1.TCP连接 手机能够使用联网功能是因为手机底层实现了TCP/IP协议,可以使手机终端通过无线网络建立TCP连接.TCP协议可以对上层网络提供接口,使上层网络数据的传输建立在“无差别”的网络之上. ...

  10. 每个JavaScript工程师都应懂的33个概念

    摘要: 基础很重要啊! 原文:33 concepts every JavaScript developer should know 译文:每个 JavaScript 工程师都应懂的33个概念 作者:s ...