【问题标题】:Asynchronously update progress bar base on the response from API根据 API 的响应异步更新进度条
【发布时间】:2018-08-11 23:28:39
【问题描述】:

说明

安装设备 API

我有一个安装设备的 API。当我点击它时,API 将开始安装我的设备,并返回 taskID

监控 API

然后我将使用 taskID 传递给另一个 API 调用以跟踪安装进度。

Monitor API 将返回一个介于 1 到 200 之间的整数,这是我安装进度的百分比。


我的目标

是一直调用监控API,异步实时更新我的​​进度条。到200就完成了,我会隐藏进度条并显示成功信息。


我试过了

逻辑

  1. 调用 API
  2. 等待 1 秒
  3. 如果仍未达到 200,请再次调用 API
  4. 重复
  5. 直到我得到 200%
  6. 然后退出循环
  7. 完成

核心代码

代码

var ajax = $.ajax({

    headers: {'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('value')},
    url: '/installDevice',
    type: 'POST',
    dataType: 'json',
    data: {'security-level':'medium'}

});

ajax.done(function ($installDeviceResponse) {

    console.log($installDeviceResponse);

    if($installDeviceResponse['result'][0]['status']['code'] == 0){

        var taskId = $installDeviceResponse['result'][0]['data']['task'];
        var $percent  = 0;
        do {

            $.ajax({url: '/monitor/'+taskId})
            .done(function ($percent) {
                setTimeout(function(){
                    console.log('P TaskIdResponse : ',$percent);
                    
                    // update prograssbar
                    // I don't have this yet.
                    // I'm trying to print it out for now

                }, 1000);
            });
        }
        while ($percent < 200);

    }else{
        var message = $installDeviceResponse['result'][0]['status']['message'];
        var code = $installDeviceResponse['result'][0]['status']['code'];
        console.error('Error code :  ' + code + ' ' + message );
    }

});

return;

我放了1s的定时器,因为我不想对API服务器进行DDOS。


结果

我得到的结果是无限循环。

我还没有添加进度条,因为我想先让代码在控制台中运行。我现在得到的只是加载图标。

加载图标似乎冻结了。

控制台似乎冻结了,甚至无法展开我的回复。

由于 CPU 使用率高,计算机发出大量风扇噪音。 Chrome 响应迟缓。

如何调试?

【问题讨论】:

  • 崩溃了我的浏览器测试大声笑,$percent 不会更新,所以你的 do while 会产生一个不断的 ajax 调用流,这将导致 dos..
  • @LawrenceCherone - 抱歉。我在做这个工作。测试此代码时请小心。 :)
  • 使用 websockets,而不是 ajax。对你来说好多了! Echo 是开箱即用的,您可以从代码中生成事件以更新进度的位置。你也可以很容易地设置laravel echo server
  • 理想情况下你不应该在循环中调用 api 你能绑定事件吗?可能是这样的 -dave-bond.com/blog/2010/01/JQuery-ajax-progress-HMTL5
  • $.ajax 调用是异步的,这意味着非阻塞,这意味着代码发送尽可能多的 AJAX 调用,甚至在收到第一个响应之前就可能耗尽资源。这看起来像一个无限循环,但如果资源无限,循环应该会在某个阶段结束。

标签: javascript php jquery ajax laravel


【解决方案1】:

您正在尝试以错误的方式进行投票。我将向您展示示例。

使用 Jquery ajax 的方法一

function poll(){
  $.ajax({ url: "server", success: function(data){
    //Update your dashboard gauge
    console.log('P TaskIdResponse : ',$percent); 


   }, dataType: "json", complete: poll, timeout: 2000 });
})();

一旦上一个请求结束就会轮询,速度非常快。

使用 setTimeout 的方法 2

// The setTimeout Technique (Not Recommended - No Queues But New AJAX Request Each Time ∴ Slow)
(function poll(){
  setTimeout(function(){
  $.ajax({ url: "server", success: function(data){
    //Update your dashboard gauge
    salesGauge.setValue(data.value);
    //Setup the next poll recursively
    poll();
  }, dataType: "json"});
}, 30000);
})();

我用于创建长轮询和检查用户状态的另一种方法。

 (function() {
  var status = $('.status'),
    poll = function() {
      $.ajax({
        url: 'status.json',
        dataType: 'json',
        type: 'get',
        success: function(data) { // check if available
          status.text('Offline!');
          if ( data.live ) { // get and check data value
            status.text(data.info); // get and print data string
            clearInterval(pollInterval); // optional: stop poll function
          }
        },
        error: function() { // error logging
          console.log('Error!');
        }
      });
    },
    pollInterval = setInterval(function() { // run function every 2000 ms
      poll();
      }, 2000);
    poll(); // also run function on init
})();

希望对你有帮助

【讨论】:

  • 在“方法1”中调用$.ajax之前不要忘记测试$percent,否则你会一直无限轮询。
  • @laravel:你的第一个方法是调用自己吗?它还包含一个错字。你能解决它吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-16
  • 2012-12-08
  • 2023-02-23
  • 1970-01-01
相关资源
最近更新 更多