根据 API 的响应异步更新进度条

Posted

技术标签:

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

说明

安装设备 API

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

监控 API

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

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


我的目标

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


我试过了

逻辑

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

核心代码

代码

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 调用,甚至在收到第一个响应之前就可能耗尽资源。这看起来像一个无限循环,但如果资源无限,循环应该会在某个阶段结束。 【参考方案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,否则你会一直无限轮询。 @RandomSeed 可以吗? gist.githubusercontent.com/bunlongheng/… @laravel:你的第一个方法是调用自己吗?它还包含一个错字。你能解决它吗?

以上是关于根据 API 的响应异步更新进度条的主要内容,如果未能解决你的问题,请参考以下文章

如何更新异步任务中的进度条

聊天界面之进度条cell

WPF BackGroundWord 异步加载更新进度条示例

尝试从外部脚本更新进度条时,QWidget 变得无响应[重复]

c#如何根据文件数量控制进度条

ADO异步查询显示进度条