ajax调用不平行

时间:2017-07-10 06:10:35

标签: php jquery ajax laravel

我有两个ajax调用。第一个调用是读取文件并将其保存到DB(mysql)中,并在for循环的底部设置一个" status"的会话变量。喜欢间隔。 第二个调用返回会话变量。

这是我的javascript代码:

 var interval = null;
function test(data) {
    var i = 0;
    interval = setInterval(function () {
        $.ajax({
            url: '/admin/movies/progress',
            type: "GET",
            async: true,
            dataType: "text",
            success: function (data) {
                console.log(data);
                $('#saveFileProgressBar').width(data[0]);
            },
            error: function (XMLHttpRequest, textStatus, errorThrown) {
                toastr.error('error progressbar', 'Download File');
            }
        });
        i++;
        if(i == 5){
            clearInterval(interval);
        }
    }, 500);

    $.ajax({
        url: '/admin/movies/1',
        type: "GET",
        async: true,
        dataType: "text",
        success: function (data) {
            console.log(data);

        },
        error: function (XMLHttpRequest, textStatus, errorThrown) {
            toastr.error('error', 'Download File');
        }
    });
}

这是我的laravel 5.4代码:

// Mapped to mysite.com/admin/movies/progress
public function getProgress() {   
    return Response::json(array(Session::get('progress')));
}

// Mapped to mysite.com/admin/movies/1
public function postGenerate() {
    // getting values from form (like $record_num)
    Session::put('progress', 0);
    Session::save(); // Remember to call save()

    for ($i = 1; $i < 100; $i++) {
        sleep(1);
        Session::put('progress', $i);
        Session::save(); // Remember to call save()
    }

    return "done";
}

enter image description here

/////// EDIT ///////

我的新PHP代码:

public function getProgress() {
    $rawData = file_get_contents('plugins/elFinder-2.1.25/files/data/progressFile.json');
    $cacheData = json_decode($rawData, true);
    return $cacheData;
}

public function postGenerate() {
    // getting values from form (like $record_num)
    for ($i = 0; $i < 10; $i++) {
        $data['progress'] = $i;
        $fres = fopen('plugins/elFinder-2.1.25/files/data/progressFile.json', 'w');
        fwrite($fres, json_encode($data));
        fclose($fres);
        sleep(1);
    }
    return "true";
}

我的javascript代码:

 var interval = null;
function test() {
    var i = 0;
    interval = setInterval(function () {
        $.ajax({
            url: '/admin/movies/progress',
            type: "GET",
            async: true,
            dataType: "text",
            success: function (data) {
                console.log(data);
                $('#saveFileProgressBar').width(data.progress);
            },
            error: function (XMLHttpRequest, textStatus, errorThrown) {
                toastr.error('Es ist ein Fehler aufgetreten beim Auslesen der Datei', 'Download File');
            }
        });
        i++;
        if(i == 5){
            clearInterval(interval);
        }
    }, 500);

    $.ajax({
        url: '/admin/movies/1',
        type: "GET",
        async: true,
        dataType: "text",
        success: function (data) {
            console.log(data);

        },
        error: function (XMLHttpRequest, textStatus, errorThrown) {
            toastr.error('Es ist ein Fehler aufgetreten beim Auslesen der Datei', 'Download File');
        }
    });
}

2 个答案:

答案 0 :(得分:1)

而不是使用会话使用常规文件。在脚本完成之前,会为每个唯一会话锁定会话文件。所以它不能并行运行。您可以做的是将数据存储在普通文件中并访问它。

从缓存文件中读出

 $rawData = file_get_contents('data/progressFile.json');
 $cacheData = json_decode($rawData, true);

写得像

$data['progress'] = 100;
        $fres = fopen('data/progressFile.json', 'w');
        fwrite($fres, json_encode($data));
        fclose($fres)

您可以将json数据结构用于所有会话并解析以获取特定进度数据,或者您可以将单独的文件用于ech进度数据。如果您使用一个大文件,则可能需要使用flock()在写入期间锁定文件。

答案 1 :(得分:1)

<强>请

Requests

<强>响应

Response

您好,

我刚刚对您的脚本进行了测试,响应在上面的图片中。第一个图像是AJAX请求列表。绿色的请求已完成,灰色请求仍在进行中。第二个图像按请求完成的顺序显示呼叫响应的日志(第一个完成的请求显示在顶部,依此类推......)。

图片中

1 指的是第一次AJAX通话(当然我将其重命名为 / set-progress 而不是 /管理/电影/ 1 )。随后的第二次AJAX调用标记为 2 - 6 / progress = / admin / movies / progress

我认为你的问题是后续(第二次调用)请求在第一个请求完成之前没有运行。从我的结论来看,我认为是假的。显然,我们可以看到第一个请求仍在等待,而其他请求已完成。所以,我们可以说你的请求是并行运行的。

对于您的情况,只有一个问题(最不可能;只要您有足够的资源来处理小请求),也就是说,您的服务器资源不足。意味着它没有足够的内存来提供第二次调用。由于第一次通话经过并且服务器资源不足,因此无法处理更多请求,从而阻止第二次通话,直到首次请求已经完成了。因此,第一次调用任何其他正在运行的任务/进程/请求正在消耗您的服务器资源,因此阻止了进一步的请求。

阅读有关文件被锁定的注释和上一个答案,以便并行请求无法发送到服务器或服务器无法接受并行请求。这个陈述也是不正确的。每次更新会话文件时会锁定会话文件,但这与浏览器一次发送多个请求没有任何关系。

如果文件不可用/在任何请求期间不存在, Laravel 只需会引发500错误。下面的附件图显示了案例的答案,文件不可用。

File not available

如果文件在写入时被锁定,则响应(进行呼叫)只是空的。这意味着,该文件存在但其内容目前不可用。下图显示了样本响应。

File locked during write operation

如果此答案不满足您,请点击这些链接。看看他们是否有帮助。 Link 1Link 2

我的测试环境:

  • PHP v7.0.13
  • Apache v2.4.23
  • Laravel v5.4
  • jQuery v3.2.1
  • Firefox v54.0.1
  • 平台Windows 10