专栏首页原创分享通用的组件请求管理器,解决异步请求中的后发先到的问题

通用的组件请求管理器,解决异步请求中的后发先到的问题

通用的组件请求管理器,解决异步请求中的后发先到的问题

测试方法:可以使用fiddler进行测试,选择fiddler rules菜单中的automatic breakpoints中的afterResponse,这样可以阻止后端过快地返回,从而可以自己选择哪个请求的结果先返回,实现模拟后发先到的情况。

tips:

1.每当需要取消之前发出的请求时,需要调用clearRequestId方法。 2.在优化版本中,显式定义了两种取消请求的方法,clearFormerRequest和clearFormerRequestBeforeRequest,后者用于在发送新的请求前使用,前者是没有发送新的请求,而是通过其他操作取消了请求,比如点击取消按钮。

/*
  通过id来跟踪请求和判断返回是否有效
*/
function CommonRequestIdManager() {
        if (!(this instanceof CommonRequestIdManager)) {
            return new CommonRequestIdManager();
        }
        // 是否已經取消了請求,如果是,則新建請求之前不需要再自增requestId
        this.hasCanceled = false;
        // 是否已經發送過請求
        this.haveEverMakeRequest = false;
        this.initRequestId();
    }
    CommonRequestIdManager.prototype = {
        // id初始化
        initRequestId: function() {
          this.requestId = 1;
        },
        // 获取该次请求对应的id
        getRequestId: function() {
          return this.requestId;
        },
        // 清除请求的id,把id加一,导致前面发出的请求不可用,用於沒有發送新請求,但是通過其他操作取消了請求,比如點擊取消按鈕
        clearFormerRequest: function() {
          this.hasCanceled = true;
          this.addRequestId();  
        },
        /* 
          清除请求的id,把id加一,导致前面发出的请求不可用,用於發送新請求之前使用,
          如果已經通過其他操作取消了請求,或者還沒有發送過請求,則不需要再自增requestId。
        */
        clearFormerRequestBeforeRequest: function() {
          if (!!this.hasCanceled || !this.haveEverMakeRequest) {
            return;
          }
          return this.addRequestId();  
        },
        addRequestId: function() {
          return this.requestId++;
        },
        // 获取当前的请求id
        getCurrentRequestId: function() {
          return this.getRequestId();
        },
        // 获取该次请求对应的回调
        getCb: function(cb,context) {
          var self = this;
          var requestId = this.getRequestId();
          // 每次新發送請求之前重置標記位
          this.hasCanceled = false;
          this.haveEverMakeRequest = true;
           console.log(requestId)
          return function(data) {
              // 对于返回的结果,判断回调函数绑定的id是否等于当前的请求id
              if (requestId === self.getCurrentRequestId()) {

                  cb && cb.call(context || null, data);
              }
          }
        }
    }

test.html

<!DOCTYPE html>
<html>
<head>
    <title>my login</title>
    <script type="text/javascript" src="jquery-1.10.2.js"></script>
</head>
<script type="text/javascript" src="./CommonRequestIdManager.js"></script>
<body>
    <input type="text" name="name">submit
    <script type="text/javascript">
        var commonRequestIdManager = new CommonRequestIdManager();
        $('input').on('keydown', function() {
            // 清除前面发出的所有请求
            commonRequestIdManager.clearRequestId();
            $.ajax({
                url: '1.php',
                success:commonRequestIdManager.getCb(function() {
                    console.log('success')
                }),
                error:commonRequestIdManager.getCb(function() {
                    console.log('error')
                })
            })
        })
    </script>
</body>

</html>

本文分享自微信公众号 - 编程杂技(theanarkh)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-02-24

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • js实现图的构造和遍历

    theanarkh
  • express框架layer.js源码解析

    layer.js是express框架的路由机制的底层数据结构。下面为主要源码,已经删除一些不太重要的代码。

    theanarkh
  • nodejs 14.0.0源码分析之setImmediate

    setImmediate的代码比较简单,新建一个Immediate。我们看一下Immediate的类。

    theanarkh
  • 【mybatis之批量更新】

    MySQL没有提供直接的方法来实现批量更新,但可以使用case when语法来实现这个功能。

    用户5640963
  • PHP设计模式之装饰者模式 转

    装饰者模式动态地将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案。

    双面人
  • IBM独家分享:大数据时代下的认知计算与人工智能

    关键字全网搜索最新排名 【机器学习算法】:排名第一 【机器学习】:排名第二 【Python】:排名第三 【算法】:排名第四 ? 很多科幻电影里都讲过这样的故事:...

    昱良
  • Node.js爬虫数据抓取 -- 问题总结

    为请求添加user-agent头,如取消上注释部分。(我发现,只要有了user-agent这个key,无论其value是否为空,都可以正常返回了)

    书童小二
  • Java基础-day07-知识点相关题-自定义数据类型;ArrayList

    Java基础-day07-知识点相关题 一、定义类:包含main()方法,按以下要求编写程序: 1)实例化一个ArrayList,只存储String数据: 2)...

    Java帮帮
  • [译] 首字节时间 (TTFB) 如何影响了网站性能

    原文:https://www.medianova.com/en-blog/2019/08/06/how-time-to-first-byte-ttfb-impa...

    江米小枣
  • Unity基础(4)-资源管理知识(1)

    Project窗口下的Assets文件夹下,就是用来存放资源的,为了方便,会使用文件夹的方式来对资源进行管理。但是也有一些特殊文件夹

    雷潮

扫码关注云+社区

领取腾讯云代金券