如何在执行Ajax请求时实现进度条大量的数据库更新

时间:2016-04-24 17:26:41

标签: javascript ajax codeigniter activerecord progress-bar

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

我不知道如何更好地解决这个问题。如果你能帮助我,那真的很酷。 谢谢所有

1 个答案:

答案 0 :(得分: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);

这允许您的脚本(并且只有那个)在没有时间限制的情况下运行。把它放在最顶端。请小心!