如何多次运行助手函数以检查数据库中的实时结果



我有一个使用Laravel 9的论坛项目,我已经制作了这个助手函数。

if(!function_exists('new_question')){
function new_question($c) {
$quelist = DB::table('questions')->get();
$quecount = $quelist->count();
if($quecount > $c){
return 'A new question is added.. please refresh the page..';
}
}
}

因此,它得到了当前问题的数量,如下所示:

{{ new_question($queCnt); }}

然后,它将检查$quecount是否等于$queCnt。如果没有,则打印语句A new question is added.. please refresh the page..。因此,如果添加了任何新问题,用户都会理解。但我需要在一段时间后(例如,10秒(运行这个助手函数。然而,我不知道如何在自定义时间后调用函数。

要在特定时间后运行任何函数,您可以设置间隔,例如

// Call the new_question function every 10 seconds
setInterval(new_question, 10000);
// Use an AJAX request to call the new_question function on the 
// server
function new_question(){
$.ajax({
url: '{{ url('/new_question') }}?c=10',
success: function(response) {
// Handle the response from the server
console.log(response);
}
});
}
</script>

// to receive get value update helper function 
if(!function_exists('new_question')){
function new_question() {
// Get the value of the c parameter from the query string
$c = isset($_GET['c']) ? $_GET['c'] : 0;
// Your code here...
}
}

首先,您必须计算出;内容";已经改变。使用Laravel,创建一个可以通过路由访问的函数,该函数将返回帖子的数量,然后,使用javascript,您将在一段时间内(例如5秒(调用该函数,如果自上次调用以来该数量发生了变化,则会有新的帖子,因此您应该进行一些DOM操作来更新页面以提醒用户。

你的服务器端功能很简单,类似于这样:

function count_questions() {
$quelist = DB::table('questions')->get();
$quecount = $quelist->count();
$response = array('quecount' => $quecount);
echo json_encode($response);
}

然后,确定如何通过路由表到达该功能,并使用以下jquery函数:

var quecount = 0;
$(document).ready(function() {
setInterval(function() {
$.ajax({
// change this URL to your path to the laravel function
url: 'questions/count',
type: 'GET',
dataType: 'json',
success: function(response) {
// if queuecount is 0, then set its initial value to quecount
if(quecount == 0){
quecount = response.quecount;
}
if(response.quecount > quecount){
quecount = response.quecount;
new_question_found();
}
}
});
}, 5000);
});
function new_question_found(){
$("#new_questions").html("New questions found");
}

我想到的解决方案可能过于先进或过于复杂。

此解决方案需要

  • Laravel调度程序和队列(作业(
  • 和网络推送通知(例如:一个信号(

为了减少后端的流量,您可以在后端每10秒运行一次作业(Laravel调度器和队列(。

如果问题数量增加。你可以在推送通知中调用一个api,你可以说添加了一个新的问题。

上面的工作流程没有很好地解释,但这是非常简单的术语。

例如:前端侧:

const check_new_questions = function() {
const message = 
fetch('http://yourserver.com/new_questions_endpoint');
if (message) {
// show message
}
};
// call each 10 seconds.
setInterval(check_new_questions, 10000);

然后在后端:创建一个路由new_questions_endpoint,它将调用您的函数并返回结果作为响应。

但请注意,每次从桌子上收到所有问题可能会很昂贵。Eloquent允许在不检索所有行的情况下进行计数查询。

如果没有任何形式的javascript,就无法实现这种行为。

你可以这样做的主要方法是像其他人所说的那样,通过前端设置一个间隔。如果你熟悉API和通用HTTP协议,我建议你做一个API路由来调用你的助手函数;我还建议使用空正文进行响应,并使用http状态代码来确定是否需要刷新:200表示成功且不需要刷新,205代表成功且需要刷新。

因此,您只需在超时时设置一个fetchapi调用,甚至不需要解码正文,只需使用响应状态来确定是否需要运行location.reload((.

要根据注释实现您的要求,您需要从FE创建一个向BE的ajax请求,以检查最新的问题,并根据该响应进行检查。

setInterval(function()
{ 
$.ajax({
url: "{{url('/')}}/check/questions",
type: "POST",
dataType: "json",
data: {"action": "loadlatest", "id": id},
success: function(data){
console.log(data);
},
error: function(error){
console.log("Error:");
console.log(error);
}
});
}, 10000);//time in milliseconds 

上面的js代码将创建一个到后端的ajax请求,下面的代码将获得最新的问题"id"。

$latest_id = DB::table('Questions')->select('id')->order_by('created_at', 'desc')->first();

所以要么在BE中检查它并向FE返回相应的响应,要么向FE返回最新的id并在那里检查它。然后显示刷新提示或显示toast并在5秒后刷新

为什么使用function_exists()?我认为在这种情况下没有用。

最简单的方法是使用ajax和setInterval

正面:

const check_new_questions = function() {
const data = 
fetch('http://yourserver.com/new_questions_endpoint?c=current');
if (data) {
alert(your_message);
}
};
// call each 10 seconds.
setInterval(check_new_questions, 10000);

背面:

function new_question() {
// Get the value of the c parameter from the query string
$c = isset($_GET['c']) ? $_GET['c'] : 0;
$quelist = DB::table('questions')->get();
$quecount = $quelist->count();
return ($quecount > $c);
}

我建议使用c作为最后一个id,不计算问题,只计算最后一个问题id。如果它们不同,则插入一个或多个问题。

注意如果使用此解决方案(Ajax拉取(,每个连接的用户每10秒将收到两个请求。一个用于ajax调用,一个用于数据库调用。如果你每天有10个用户,那没关系,但如果你有1万个,那就不行了。更好但更复杂的方法是使用Mercure协议或类似协议(https://mercure.rocks/(。

最新更新