我有一个使用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/(。