js中实现ajax请求轮询,以及避免第一次延迟

简介: js中实现ajax请求轮询,以及避免第一次延迟

对于轮询功能的实现,查找相关的资料,大都是使用window setInterval()方法,该方法的语法和用法如下:


Window setInterval() 方法


定义和用法


setInterval() 方法可按照指定的周期(以毫秒计)来调用函数或计算表达式。


setInterval() 方法会不停地调用函数,直到 clearInterval() 被调用或窗口被关闭。由 setInterval() 返回的 ID 值可用作 clearInterval() 方法的参数。


提示: 1000 毫秒= 1 秒。


提示: 如果你只想执行一次可以使用 setTimeout() 方法。


语法


setInterval(code, milliseconds);

setInterval(function, milliseconds, param1, param2, ...)

看到的很多文章使用都是单独构建一个function然后通过setInterval()调用它。但是有时候有些请求操作获取数据一般立即需要返回用于显示,为此不太好封装成function。那么又该怎么去使用它?


在我的项目中,需要实现连续两个ajax的请求,作用:第一个request,第二个是get,得到数据后需要进行显示。而get请求需要准备时间,需要轮询请求。那么设计如下:

return $.ajax({
    url: dataport+"/rest/request",
    type: "POST",
    data: postdata,
    contentType:"application/json",
    success: (function(_this) {
       return function(data) {
          if(data.message === 'success'){
              console.log("token: "+data.token);
              var webinfo2 = {"kind":kindindex,
                              "userid":userid,
                              "token":data.token};
              var postdata2 = JSON.stringify(webinfo2);
              var count = 0 ;      
              //加一个轮询等待机制
              this.timeId = window.setInterval(()=>{
                 if(navdata !== 0){
                      console.log("last count,end poling:"+count);
                      window.clearInterval(this.timeId);
                 };return $.ajax({
                      url: dataport+"/rest/get",
                      type: "POST",
                      data: postdata2,
                      contentType:"application/json",
                      async: true,
                      cache: true,
                      success: function (datas) {
                           count++;
                           console.log("the count is : "+count);
                           navdata = datas.status;//全局变量
                           if (datas.status === 0) {
                              console.log("数据准备中,请等待!");
                              //return _this.$el.find(".data-manage-bottom #data-list").html('<div class="data-managet-warning"><h3>数据准备中,请等待...</h3></div>');
                           }
                           else if (datas.status === 2) {
                              return _this.$el.find(".data-manage-bottom #data-list").html('<div class="data-managet-warning"><h3>暂无数据,数据准备失败!</h3></div>');
                           }
                           else if (datas.status === 1) {                           
                              console.log(datas.url);
                              console.log(datas.url.length);
                              return _this.renderList(datas.url);//显示
                           }
                           if(count === 60)//设置5分钟的轮询超时机制
                           {
                              navdata = -1;
                              return _this.$el.find(".data-manage-bottom #data-list").html('<div class="data-managet-warning"><h3>数据准备超时,请过段时间再访问!</h3></div>');
                           }
                      }
                 });
              },5000);//5秒一次
          }
       }
   })(this)
});

可以将轮询功能抽象出来为:


this.timeId = window.setInterval(()=>{

if(跳出条件){

  window.clearInterval(this.timeId);

};{执行代码块或者函数};},5000);


这样就比较方便了,不用总是想着去构建function,毕竟很多代码块重新封装成function使用起来很不方便。这里直接将需要轮询执行的代码块放在其中,这样就能够实现了对这部分的重复循环。


以上的代码,在执行过程中,会发现每次请求需要等待一段时间,往往我们轮询是第一次不需要等待的。那么如何避免第一次延迟呢?


为此网上有很多的解决方法:比如js中函数参数如果是”函数名+()“,则会先执行函数,然后将返回值作为真正的参数。相反参数没加“()”则会被作为一个函数块指针,不先执行。在调用function时写成function();还有说使用递归之类的。但对于我们来说,最简单就是第一次重复执行一下就行了。代码如下:

return $.ajax({
    url: dataport+"/rest/request",
    type: "POST",
    data: postdata,
    contentType:"application/json",
    success: (function(_this) {
        return function(data) {
           if(data.message === 'success'){
               console.log("token: "+data.token);
               var webinfo2 = {"kind":kindindex,
                  "userid":userid,//webuserInfo1.userid.toString(),
                  "token":data.token};
               var postdata2 = JSON.stringify(webinfo2);
               var count = 0 ;
               //避免第一次延时
               return $.ajax({
                   url: dataport+"/rest/get",
                   type: "POST",
                   data: postdata2,
                   contentType:"application/json",
                   async: true,
                   cache: true,
                   success: function (datas) {
                       count++;
                       console.log("the count is : "+count);
                       navdata = datas.status;
                       if (datas.status === 0) {
                           console.log("数据准备中,请等待!");
                           _this.$el.find(".data-manage-bottom #data-list").html('<div class="data-managet-warning"><h3>数据准备中,请等待...</h3></div>');
                       }
                       else if (datas.status === 2) {
                           return _this.$el.find(".data-manage-bottom #data-list").html('<div class="data-managet-warning"><h3>暂无数据,数据准备失败!</h3></div>');
                       }
                       else if (datas.status === 1) {
                           console.log(datas.url);
                           console.log(datas.url.length);
                           return _this.renderList(datas.url);
                       }
                       //加一个轮询等待机制
                       this.timeId = window.setInterval(()=>{
                          if(navdata !== 0){
                            console.log("last count,end poling:"+count);
                            window.clearInterval(this.timeId);
                          };return $.ajax({
                             url: dataport+"/rest/get",
                             type: "POST",
                             data: postdata2,
                             contentType:"application/json",
                             async: true,
                             cache: true,
                             success: function (datas) {
                               count++;
                               console.log("the count is : "+count);
                               navdata = datas.status;
                               if (datas.status === 0) {
                                 console.log("数据准备中,请等待!");
                                 //return _this.$el.find(".data-manage-bottom #data-list").html('<div class="data-managet-warning"><h3>数据准备中,请等待...</h3></div>');
                               }
                               else if (datas.status === 2) {
                                 return _this.$el.find(".data-manage-bottom #data-list").html('<div class="data-managet-warning"><h3>暂无数据,数据准备失败!</h3></div>');
                               }
                               else if (datas.status === 1) {
                                 console.log(datas.url);
                                 console.log(datas.url.length);
                                 return _this.renderList(datas.url);
                               }
                               if(count === 60)//设置5分钟的轮询超时机制
                               {
                                 navdata = -1;
                                 return _this.$el.find(".data-manage-bottom #data-list").html('<div class="data-managet-warning"><h3>数据准备超时,请过段时间再访问!</h3></div>');
                             }
                          }
                       });
                       },5000);
                   }
               });
            }
         }
    })(this)
});

这样抽象出来就是:


{执行的代码块或函数};


this.timeId = window.setInterval(()=>{

if(跳出条件){

window.clearInterval(this.timeId);

};{执行代码块或者函数};},5000);


以上代码看起来是不是显得冗余和难看,但这是最简单的实现方法。

目录
相关文章
|
16天前
|
JavaScript 前端开发 容器
AJAX载入外部JS文件到页面并让其执行的方法(附源码)
AJAX载入外部JS文件到页面并让其执行的方法(附源码)
17 0
|
17天前
sd.js 2.0封装:更加简化请求传参内容(逐步废弃、逐渐日落2024.01.02)
sd.js 2.0封装:更加简化请求传参内容(逐步废弃、逐渐日落2024.01.02)
|
1月前
|
JavaScript 前端开发 Java
springboot从控制器请求至页面时js失效的解决方法
springboot从控制器请求至页面时js失效的解决方法
15 0
springboot从控制器请求至页面时js失效的解决方法
|
1月前
|
JSON JavaScript 前端开发
解决js中Long类型数据在请求与响应过程精度丢失问题(springboot项目中)
解决js中Long类型数据在请求与响应过程精度丢失问题(springboot项目中)
41 0
|
1月前
|
JavaScript 前端开发
springboot+layui从控制器请求至页面时js失效的解决方法
springboot+layui从控制器请求至页面时js失效的解决方法
15 0
|
1月前
|
缓存 JavaScript 前端开发
一次js请求一般情况下有哪些地方会有缓存处理?
一次js请求一般情况下有哪些地方会有缓存处理?
18 1
|
1月前
|
数据采集 JavaScript 前端开发
利用axios库在Node.js中进行代理请求的实践
利用axios库在Node.js中进行代理请求的实践
|
1月前
|
JavaScript 前端开发
node.js第四天--ajax在项目中的应用
node.js第四天--ajax在项目中的应用
27 0
|
1月前
|
XML 前端开发 JavaScript
node.js第三天-----ajax(3)
node.js第三天-----ajax(3)
26 0
|
6月前
|
前端开发 JavaScript
$.ajax GET请求案例
$.ajax GET请求案例
22 0