Php ajax调用不是并行的

Php ajax调用不是并行的,php,jquery,ajax,laravel,Php,Jquery,Ajax,Laravel,我有两个ajax调用。第一个调用是for读取文件并将其保存到DB(mysql)中,在for循环的底部,他们设置了一个“status”会话变量,如interval。 第二个调用返回会话变量 这是我的javascript代码: var interval = null; function test(data) { var i = 0; interval = setInterval(function () { $.ajax({ url: '/ad

我有两个ajax调用。第一个调用是for读取文件并将其保存到DB(mysql)中,在for循环的底部,他们设置了一个“status”会话变量,如interval。 第二个调用返回会话变量

这是我的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');
        }
    });
}
 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');
        }
    });
}
这是我的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";
}

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

从缓存文件中读取

 $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)
像这样写

 $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()
锁定该文件。

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

从缓存文件中读取

 $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)
像这样写

 $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()
在写入过程中锁定该文件。

请求

响应

 $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)

我刚刚对你的脚本进行了测试,结果如上图所示。第一幅图是AJAX请求的列表。绿色的是已完成的请求,灰色的仍在进行请求。第二幅图按请求完成的顺序显示调用响应日志(第一个完成的请求显示在顶部,依此类推)

图像中的1指的是第一个AJAX调用(当然我将其重命名为/set progress,而不是/admin/movies/1)。随后的第二次AJAX调用被标记为2-6,并且 /progress=/admin/movies/progress

我认为您的问题在于,后续(第二次调用)请求在第一次调用完成之前不会运行。根据我的测试,我认为是错误的。我们可以清楚地看到,第一个请求仍然悬而未决,而其他请求已经完成。因此,我们可以说您的请求是并行运行的

对于您的情况,可能只有一个问题(可能性最小;前提是您有足够的资源来处理一个小请求),即您的服务器资源不足。这意味着它没有足够的内存来处理第二次呼叫。由于第一次调用已通过,且服务器资源不足,因此无法处理进一步的请求,因此在第一次请求完成之前,服务器将阻止第二次调用。因此,您的第一次调用任何其他正在运行的任务/进程/请求正在消耗您的服务器资源,因此会阻止进一步的请求

正在阅读有关文件被锁定的注释和以前的答案,以便无法将并行请求发送到服务器或服务器无法接受并行请求。这种说法也不正确。每次更新会话文件时都会锁定会话文件,这是真的,但这与浏览器一次发送多个请求无关

如果在任何请求过程中文件不可用/不存在,Laravel只是抛出一个500错误。下图显示了对该案例的响应,该文件不可用

如果文件在写入时被锁定,响应(到进程调用)就是空的。这意味着,该文件存在,但其内容目前不可用。下图显示了一个示例响应

如果这个答案不能让你满意,请点击以下链接。看看他们是否能帮上忙。 和

我的测试环境: