Php ajax调用不是并行的
我有两个ajax调用。第一个调用是for读取文件并将其保存到DB(mysql)中,在for循环的底部,他们设置了一个“status”会话变量,如interval。 第二个调用返回会话变量 这是我的javascript代码: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
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错误。下图显示了对该案例的响应,该文件不可用
如果文件在写入时被锁定,响应(到进程调用)就是空的。这意味着,该文件存在,但其内容目前不可用。下图显示了一个示例响应
如果这个答案不能让你满意,请点击以下链接。看看他们是否能帮上忙。
和
我的测试环境:
- PHP v7.0.13
- Apache v2.4.23
- Laravel v5.4
- jQuery v3.2.1
- Firefox v54.0.1
- 平台视窗10
- 请求
响应
$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
我认为您的问题在于,后续(第二次调用)请求在第一次调用完成之前不会运行。根据我的测试,我认为是错误的。我们可以清楚地看到,第一个请求仍然悬而未决,而其他请求已经完成。因此,我们可以说您的请求是并行运行的
对于您的情况,可能只有一个问题(可能性最小;前提是您有足够的资源来处理一个小请求),即您的服务器资源不足。这意味着它没有足够的内存来处理第二次呼叫。由于第一次调用已通过,且服务器资源不足,因此无法处理进一步的请求,从而阻止第二次调用