在不用Promise的情况下如何控制异步请求?

  如何更好的控制异步请求?相信大家一定首选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!

时间: 2024-08-19 14:31:37

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

linux下tomcat部署get请求乱码问题解决方法

默认情况下,Tomcat对请求采用的默认编码是ISO-8859-1, 这样我们提交的汉字被认为是ISO-8859-1的编码,所以在程序中接收时显示乱码 .  在过滤器中调用request.setCharacterEncoding("GBK"),那么Post上来的汉字将被认为是GBK编码,而 Tomcat5对于Get请求上来的编码并不根据过滤器的设定辨认编码方式,默认的依然是ISO-8859-1,所以,即使你的页面使用默认的编码方式进 行编码,然后使用ISO-8859-1进行解码,得到的

C++学习之构造函数和拷贝控制--什么样的情况下才需要虚析构函数

什么样的情况下才需要虚析构函数? 类需要控制自己的对象执行一系列操作时发生什么样的行为,这些操作包括:创建(对象).拷贝.移动.赋值和销毁.在继承体系中,如果一个类(基类或其派生的类)没有定义拷贝控制操作,则编译器将自动的为其合成一个.即为合成的拷贝控制. 在基类的拷贝控制中,由于继承关系导致的最大影响就是:基类通常应该定义一个‘虚析构函数’.用以动态的分配继承体系中的对象. 如:类A,B,C,D有如下继承关系(代码1): 1 2 3 4 class A; class B:public A; c

c#中跨线程调用windows窗体控件 .我们在做winform应用的时候,大部分情况下都会碰到使用多线程控制界面上控件信息的问题。然而我们并不能用传统方法来做这个问题,下面我将详细的介绍。

首先来看传统方法: public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { Thread thread = new Thread(ThreadFuntion); thread.IsBackground = true; thread.Start(); } private void Thread

尝试加载 Oracle 客户端库时引发 BadImageFormatException。如果在安装 32 位 Oracle 客户端组件的情况下以 64 位模式运行,将出现此问题。

从10G开始,Oracle提供了一个较为轻量级的客户包,叫做Instant Client. 将它安装好后,就不用再安装庞大的Oracle Client了. 这样一来,只要客户端下载Instant Client,直接解压,设置Path就ok了.具体设置如下:1.下载32位Oracle InstantClient 2.将Oracle InstantClient解压到某目录 3.打开PL/SQL,在perference里面设置OCI Library和Oracle_home,例子如下:        

无RMAN备份集情况下的坏块恢复

测试的环境是没有可用的RMAN备份集,但是有数据文件的热备,下面来看测试: --创建测试用户和测试表 [[email protected] ~]$ sqlplus / as sysdba SQL*Plus: Release 10.2.0.1.0 - Production on 16 16:01:02 2014 Copyright (c) 1982, 2005, Oracle.  All rights reserved. Connected to: Oracle Database 10g Ente

服务器上的Mysql表全丢了情况下恢复数据

任务: web项目是在linux的Tomcat部署,Mysql也在上面,不知明原因下数据库宕机,启动不了,数据库表也突然没了,全空了!!!!!!!! mysql安装目录 惊喜的发现var/目录下有类似丢失数据库的表 接下来就是怎么恢复进去了,首先我们用的是mysql的InnoDb引擎,找了下其资料: 两种类型最主要的差别就是Innodb 支持事务处理与外键和行级锁.而MyISAM不支持.所以MyISAM往往就容易被人认为只适合在小项目中使用. 我作为使用MySQL的用户角度出发,Innodb和M

mysql什么情况下会触发表锁

锁是计算机协调多个进程或线程并发访问某一资源的机制.在数据库中,除传统的计算资源(如CPU.RAM.I/O等)的争用以外,数据也是一种供许多用户共享的资源.如何保证数据并发访问的一致性.有效性是所有数据库必须解决的一个问题,锁冲突也是影响数据库并发访问性能的一个重要因素.从这个角度来说,锁对数据库而言显得尤其重要,也更加复杂.本章我们着重讨论MySQL锁机制的特点,常见的锁问题,以及解决MySQL锁问题的一些方法或建议. MySQL锁概述 相对其他数据库而言,MySQL的锁机制比较简单,其最显著

es 在数据量很大的情况下(数十亿级别)如何提高查询效率啊?

面试题es 在数据量很大的情况下(数十亿级别)如何提高查询效率啊?面试官心理分析这个问题是肯定要问的,说白了,就是看你有没有实际干过 es,因为啥?其实 es 性能并没有你想象中那么好的.很多时候数据量大了,特别是有几亿条数据的时候,可能你会懵逼的发现,跑个搜索怎么一下 5~10s,坑爹了.第一次搜索的时候,是 5~10s,后面反而就快了,可能就几百毫秒.你就很懵,每个用户第一次访问都会比较慢,比较卡么?所以你要是没玩儿过 es,或者就是自己玩玩儿 demo,被问到这个问题容易懵逼,显示出你对

MySQL分页优化中的“INNER JOIN方式优化分页算法”到底在什么情况下会生效?

本文出处:http://www.cnblogs.com/wy123/p/7003157.html 最近无意间看到一个MySQL分页优化的测试案例,并没有非常具体地说明测试场景的情况下,给出了一种经典的方案,因为现实中很多情况都不是固定不变的,能总结出来通用性的做法或者说是规律,是要考虑非常多的场景的,同时,面对能够达到优化的方式要追究其原因,同样的做法,换了个场景,达不到优化效果的,还要追究其原因.个人对此场景在不用情况表示怀疑,然后自己测试了一把,果然发现一些问题,同时也证实了一些预期的想法.