【问题标题】:How to implements Progress bar when doing Ajax request Voluminous db updates执行 Ajax 请求大量数据库更新时如何实现进度条
【发布时间】:2016-04-24 17:26:40
【问题描述】:

早上好, 我有更新大量数据的脚本(例如 3000Lines),我必须在进度条上向用户显示数据库更新的进度或受影响的行数。 我正在研究 PHP codeigniter 和 AJAX 我有一个想法,使用会话 codeigniter 将修改后的变量(增量)存储在每个循环上的会话值上,并调用将会话变量作为 JSON 数组提供给我的函数,但问题是会话在第一次更新后不会自行改变(例如:从0开始修改为20,之后所有进程都在20)

我不知道如何获得更好的解决方案。如果你能帮助我,那将是非常酷的。 谢谢大家

【问题讨论】:

    标签: javascript ajax codeigniter activerecord progress-bar


    【解决方案1】:

    在脚本完全完成之前,PHP 不会输出任何内容,但您可以更改:

    ob_implicit_flush(true);
    for ($i = 0; $i < ob_get_level(); $i++) {
        ob_end_clean();
    }
    

    在开始处理数据之前将其放入您的 PHP 脚本中。当您处理部分数据时,输出一些内容来告诉 AJAX 请求进度;例如:

    PHP:

    $completed_updates = 0;
    $last_echoed_progress = 0;
    $progress_echo_interval_seconds = 2;
    while ($completed_updates < $amount_of_db_updates_to_do) {
        do_db_update();
        $completed_updates++;
        if ($last_echoed_progress + $progress_echo_interval_seconds < time()) {
            echo ($completed_updates / $amount_of_db_updates_to_do) * 100;
            $last_echoed_progress = time();
        }
    }
    

    jQuery 的 .ajax 也(默认情况下)在接收到所有数据(即脚本结束)之前不会使用数据调用成功函数,因此创建一个自定义 XHR 对象,其中包含一个事件侦听器,该对象在脚本仍在运行:

    JS:

    var last_response_length = 0;
    $.ajax({
        ... // All your other settings
        xhr: function() {
            var xhr = new XMLHttpRequest(); // Create a custom XHR object
    
            xhr.onprogress = function(data) {
                var response = data.currentTarget.response, // Get the output
                    progress = response.slice(last_response_length) | 0; // Remove old output
    
                $( '#progress-bar' ).val(progress); // Update the progress bar
                last_response_length = response.length; // Track where the old data is (so they can be removed when new data is received)
            };
            return xhr; // IMPORTANT! Return the custom XHR for .ajax to use
        },
        success: function(response) {
            $( '#progress-bar' ).val(100); // All done!
        }
    });
    

    显然修改代码以满足您的需要,并进行一些试验。请记住,PHP 的默认执行时间限制为 30 秒,因此您可能需要在脚本中进行更改:

    set_time_limit(0);
    

    这使您的脚本(并且只有那个)可以不受时间限制地运行。把它放在最上面。谨慎使用!

    【讨论】:

    • 我会试试看是否可以告诉你,非常感谢
    • 它似乎工作谢谢,但小问题:当它改变例如 44 到 45 时,很多时候它显示 4445 和 45 (擦除) 47 等之后......我认为执行速度有问题。有什么想法可以解决这个问题?
    • @NeoFethiCh 嗯,很有趣...稍后我会更深入一些,但现在您可以尝试在 PHP 中的 for 循环之外使用 echoing,每隔一段时间输出进度而不是每次迭代(例如while (true) { if ($last_echo + 2 &lt; time()) echo $progress; $last_echo = time() })。不过可能是 JS 问题...
    • @NeoFethiCh 我已经更新了代码,以便只在定时间隔内输出进度。
    • 它似乎工作了!完美的 !非常感谢
    猜你喜欢
    • 1970-01-01
    • 2017-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-23
    相关资源
    最近更新 更多