如何更好的控制异步请求?相信大家一定首选Promise对象。确实,使用Promise控制异步请求确实非常方便,直接使用then()方法就可以实现当一个异步请求完成后再处理另一个请求或操作。同时,这样的代码也避免了使用大量的回调函数造成的“丑陋的代码”。

  不过,在实际的工作中却总是不能尽人意。虽然es6越来越普及,但偶尔也会遇到一些维护老项目的情况,况且Promise的兼容性也是个问题......

恰好我今天也遇到了这个问题,不过情况更加复杂一些。简单描述一下就是——老项目有一个需求就是给一个游戏新增一个小结页,把原来老的小结页(写在iframe里)去掉。直接结果就是页面的按钮减少了,但事件数量不变,且都绑在了一个按钮上。这个按钮点击后意味着做完一道题,就要做一次异步请求来保存答案,然后判断是最后一题的话点击后会触发iframe的postMessage且切换页面,之后还有一次异步请求。由于全部是异步请求,这也直接导致了如果请求速度比较慢的话,页面先postMessage切换页面后,请求直接会shutdown掉!

 

所以要改的目的也很明确,就是当做到最后一题的时候,先执行完两个异步请求,最后再postMessage切换页面。老司机肯定都知道如果不能用Promise的话直接用回调函数就好了。不过这两个异步请求没有绑定在一起,所以想直接用回调函数也不是那么容易。我想了很久,实在搞不定,后来找leader,leader用一个巧妙的方法帮我搞定了。(我遇到的情况可能比较特殊,不过leader的这个思路确实非常棒)下面直接show给大家看!

$("#next").click(function(){ //每做完一题点击按钮保存
saveQuestion(title); //执行保存游戏的异步操作 if(....){
//执行一些操作
}; if(....){
//执行一些操作
}; if(game.over == true){ //当做到最后一题时会触发
postMessage(title); //iframe postMessage出去并切换页面,此时saveQuestion和saveTask没有完成请求的话会被shut down; saveTask(title); //执行第二个异步请求
} })

如果按照上述代码做的话请求会被关闭掉,原因我也说了,那么此时我们该如何做才能保证两个请求执行完再执行postMessage的操作呢?

$("#next").click(function(){
var flags = {
done:false
};
savaQuestiontitle, flags); if..... if..... if(game.over == true){
var showPostMessage = postMessage.bind(undefined,title);
var callback = function(flags,func){
while(flags.done == false){};
func();
}
callback = callback.bind(undefined,flags,postMessage);
     saveTask(title,callback);
    }
})

只要把代码写成这样就可以成功运行了!有的朋友可能看不懂,别急,我一句一句来分析!

首先先写一个flags对象,将flags作为参数传入异步请求的函数中,这个对象的作用主要用来控制异步请求的完成。只有当saveQuestion内的请求success或error后,将flags的done属性变为true;之后便是一系列if的判断,我们暂且省略;直到游戏结束时,我们声明一个回调函数callback ,这个回调函数传入两个参数,一个是flags对象,另一个是函数(即posMessaget);callback内部先是使用一个while循环,在flags.done为false时不停的循环,什么也不做。根据前面我们知道只有在saveQusetion异步请求结束后flags.done才会为true,所以说这个回调函数是为了控制saveQuestion的;

最后,我们再将回调函数放入saveTask中作为第二个参数,只有当saveTask请求结束后才调用callback!这样一来我们就可以保证整个程序先执行saveQuestion,虽然不知道saveQuestion什么时候请求结束,但可以通过flags.done来判断;之后执行saveTask,只有执行完saveTask后才会执行回调函数;如果此时saveQuestion请求还没结束,callback会在内部使用while等待请求,只有成功后才会执行最后的postMessage!

在不用Promise的情况下如何控制异步请求?的更多相关文章

  1. # Volley源码解析(二) 没有缓存的情况下直接走网络请求源码分析#

    Volley源码解析(二) 没有缓存的情况下直接走网络请求源码分析 Volley源码一共40多个类和接口.除去一些工具类的实现,核心代码只有20多个类.所以相对来说分析起来没有那么吃力.但是要想分析透 ...

  2. 下一个ajax异步请求被挂起问题

    异步请求按理来说应该是会不受其它ajax请求影响的,但如果是服务端访问了Session就不能这么说了. 了解了asp.net的会话管理,那我们来看看今天要谈到的主题: IReadOnlySession ...

  3. Chrome下解决本地异步请求失败的问题(Origin null is not allowed by Access-Control-Allow-Origin. )

    Chrome更新版本后发现打开本地Jquery easyui没有数据,查看控制台才发现如下问题解决的办法是设置启动参数"--allow-file-access-from-files" ...

  4. 没有Promise的时候自己处理复合异步请求

    function getList(options){ $.ajax(success:funciton(){ if(options.callback) options.callback.call(); ...

  5. 关于MySQL什么时候使用索引问题以及什么情况下应不建或少建索引

    一,什么情况下使用索引1. 表的主关键字 自动建立唯一索引 2. 表的字段唯一约束 ORACLE利用索引来保证数据的完整性 3. 直接条件查询的字段 在SQL中用于条件约束的字段 如zl_yhjbqk ...

  6. @Java Web 程序员,我们一起给程序开个后门吧:让你在保留现场,服务不重启的情况下,执行我们的调试代码

    一.前言 这篇算是类加载器的实战第五篇,前面几篇在这里,后续会持续写这方面的一些东西. 实战分析Tomcat的类加载器结构(使用Eclipse MAT验证) 还是Tomcat,关于类加载器的趣味实验 ...

  7. django后台使用MySQL情况下的事务控制详解

    写在前面: 默认情况下django会把autocommit设置为“1”也就是说所针对数据库的每一次操作都会被做成“单独”的一个事务:这样的处理好处就在于它方便, 在编程的时候可以少写一些代码,比如我们 ...

  8. Oracle 无备份情况下的恢复--控制文件/数据文件

    13.3无备份恢复控制文件 没有备份恢复控制文件其实就是在nomount状态,create control创建一个新的控制文件. dba必须知道4个信息才能正确的创建:数据库名.在线日志路径及其大小. ...

  9. DNS分别在什么情况下使用UDP和TCP

    DNS同时占用UDP和TCP端口53是公认的,这种单个应用协议同时使用两种传输协议的情况在TCP/IP栈也算是个另类.但很少有人知道DNS分别在什么情况下使用这两种协议.     如果用wiresha ...

随机推荐

  1. 2016-2017-2 《Java 程序设计》课堂实践项目

    目录 基本工具 基础内容 Hello World 和 模块分解 数组的使用 命令行参数 递归 分支语句 String类的使用 类的定义与测试 多态 IO与异常 数据库 网络与安全 数据结构应用 And ...

  2. 【Beta】 第五次Daily Scrum Meeting

    一.本次会议为第五次meeting会议 二.时间:10:00AM-10:20AM 地点:陆大楼 三.会议站立式照片 四.今日任务安排 成员 昨日任务 今日任务 林晓芳 帮助完善登录界面 对目前完成的模 ...

  3. 201521123054《Java程序设计》第8周学习总结

    1. 本周学习总结 2. 书面作业 List中指定元素的删除(题目4-1) 1.1 实验总结 每次删除时下标需要-1:原理如图 统计文字中的单词数量并按出现次数排序(题目5-3) 2.1 伪代码(简单 ...

  4. 201521123037 《Java程序设计》第2周学习总结

    1. 本周学习总结 初步学会分析使用命令提示符进行编译的命令 了解使用import引入不同包的类 学会码云与eclipse的连接 使用Array和String函数编写程序 2. 书面作业 1. 使用E ...

  5. 201521123051《Java程序设计》第十二周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多流与文件相关内容. 一 JAVA语言中主要通过流来完成IO操作. 流:计算机的输入输出之间流动的数据序列,也是类的对象.java中 ...

  6. openfire:基于开源 Openfire 聊天服务器 - 开发Openfire聊天记录插件

    基于开源 Openfire 聊天服务器 - 开发Openfire聊天记录插件 上一篇文章介绍到怎么在自己的Java环境中搭建openfire插件开发的环境,同时介绍到怎样一步步简单的开发openfir ...

  7. lintcode.44 最小子数组

    最小子数组   描述 笔记 数据 评测 给定一个整数数组,找到一个具有最小和的子数组.返回其最小和. 注意事项 子数组最少包含一个数字 您在真实的面试中是否遇到过这个题? Yes 哪家公司问你的这个题 ...

  8. SVM原理以及Tensorflow 实现SVM分类(附代码)

    1.1. SVM介绍 1.2. 工作原理 1.2.1. 几何间隔和函数间隔 1.2.2. 最大化间隔 - 1.2.2.0.0.1. \(L( {x}^*)\)对$ {x}^*$求导为0 - 1.2.2 ...

  9. Sql Server——运用代码创建数据库及约束

    在没有学习运用代码创建数据库.表和约束之前,我们只能用鼠标点击操作,这样看起来就不那么直观(高大上)了. 在写代码前要知道在哪里写和怎么运行: 点击新建查询,然后中间的白色空白地方就是写代码的地方了. ...

  10. js如何获取客户端IP

    1.在HTML页面里面引入<script src="http://pv.sohu.com/cityjson?ie=utf-8"></script> 2.获取 ...