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);

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

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

nanke_yh

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值