頁面的資料因需要即時性的關系,大概每1秒左右會呼叫一次ajax,並清除瀏覽器上的畫面然後再把取得的資料加到頁面上,反覆下來幾百次後,畫面會卡住,無法流暢的去操作畫面。
目前是有在ajax cache設定成false,但測試後還是有一樣的問題。
想請教各位這是什麼原因造成的?又該如何解決這個問題?
感謝各位~
function SetDetail(){
$.ajax({
crossDomain: true,
url: url,
method: "POST",
data: obj,
cache:false,
success: function (response) {
$('.tablebox').children().remove();
$.each(response,function(i,v){
var $ul = $('<ul/>').addClass('item')
$ul.append('<li>'+v.ID+'</li>');
$ul.append('<li>'+v.Name+'</li>');
$ul.append('<li>'+v.County+'</li>');
$('.tablebox').append($ul);
})
}
});
}
setInterval(function(){SetDetail();},1000);
ajax是非同步模式,你前項工作可能沒完成,後面又來個新的ajax request ...........
不卡都難
解決方法,不用setinterval,用settimeout
function SetDetail(){
$.ajax({
crossDomain: true,
url: url,
method: "POST",
data: obj,
cache:false,
success: function (response) {
$('.tablebox').children().remove();
$.each(response,function(i,v){
var $ul = $('<ul/>').addClass('item')
$ul.append('<li>'+v.ID+'</li>');
$ul.append('<li>'+v.Name+'</li>');
$ul.append('<li>'+v.County+'</li>');
$('.tablebox').append($ul);
})
setTimeout(SetDetail,1000); // 跑完上述工作......再設定一次timeout,周而復始,保証不會同時有兩個ajax在工作
}
});
}
//這個搬進document ready裡
$(document).ready(function () {
setTimeout(SetDetail,1000); // ←只讓他跑一次
);
打邊爐,SetInterval跟SetTimeout的差別
https://kuro.tw/posts/2019/02/23/%E8%AB%87%E8%AB%87-JavaScript-%E7%9A%84-setTimeout-%E8%88%87-setInterval/
再打個邊爐
為什麼要$(document).ready.............
因為這事件只會發生在頁面BODY完成載入之後,不然如果你把這個js檔掛在<head></head>裡,就會發生找不到你要的elements狀況,或許JQ已有處理好這鳥事,但絕不是個好習慣
也許是你引用的 setinterval(....) 那句刻意省掉ready或 body onload........那就當我沒打這邊爐吧
再打一個邊,ajax非同步是什麼意思.....就是在發動AJAX時並不會死鎖你的系統(或瀏覽器),AJAX畢竟是網路操作,要是網路塞車、斷線、或是電腦正在烤肉片.....你的AJAX就不會馬上完成工作,你用setinterval並不會檢查上一個ajax是否已經完成工作,一秒後又再發動一個新的AJAX..............如果網路持續塞,你的未完成工作就會一直堆積,直到瀏覽器受不鳥發出哀號........其實是警告,告訴你你的網站似乎有些問題沒有回應,然後你的記憶體也會跟我的錢包一樣,愈來愈乾扁.....
補一下浩大的指導
function SetDetail(){
$.ajax({
crossDomain: true,
url: url,
method: "POST",
data: obj,
cache:false,
success: function (response) {
$('.tablebox').children().remove();
$.each(response,function(i,v){
var $ul = $('<ul/>').addClass('item')
$ul.append('<li>'+v.ID+'</li>');
$ul.append('<li>'+v.Name+'</li>');
$ul.append('<li>'+v.County+'</li>');
$('.tablebox').append($ul);
})
setTimeout(SetDetail,1000);
},
error: function(){
setTimeout(SetDetail,1000);
}
});
}
$(document).ready(function () {
setTimeout(SetDetail,1000);
);
使用ajax,由於是非同步的關係。
如果是需要計時運行,要事先了解到幾件事
1.是否可以後蓋前行為。
2.是否運行的動作能在時限內完成。(這點很重要)
3.是否有清畫面或是蓋元件的動作。
一般來說,ajax的動作,如果需要定時處理的。我大多不會用1秒來處理。
依照你的程式碼來看,你因該是需要讀取資料並做each調整畫面。
使用1秒的時間太短了。你會無形中造成堆積程序而把瀏覽器給炸了。
基本如果需要有即時性。但讀取資料會超過1秒的情況。
我會建議用一個ajaxing的參數來做判斷。讓你的程序保証不會超過2次ajax請求。
大略如以下的寫法
var ajaxing=0;//預設動作為0
setInterval(function(){
if(ajaxing==0){//判斷還未開始ajax
ajaxing=1;//設定ajax開始
$.ajax({
crossDomain: true,
url: url,
method: "POST",
data: obj,
cache:false,
success: function (response) {
$('.tablebox').children().remove();
$.each(response,function(i,v){
var $ul = $('<ul/>').addClass('item')
$ul.append('<li>'+v.ID+'</li>');
$ul.append('<li>'+v.Name+'</li>');
$ul.append('<li>'+v.County+'</li>');
$('.tablebox').append($ul);
})
ajaxing=0;//設定ajax處理結束
},
error:function(XMLHttpRequest, textStatus, errorThrown){
console.log(XMLHttpRequest.responseText);
ajaxing=0;//設定ajax處理結束
}
});
}
},1000);
japhenchen 的方式也是一種。不過他是有危險的。一但ajax發生任何請求問題。
就會停止了。這就得看方法使用了。
其實我不用 settimeout 還有另一個因素啦。
就是還要再用一個function處理。
我是不太敢完全信賴js的變數,不過網頁有個特性,出錯了就停止往後的工作,免得一個錯誤引發更多的錯誤,但要做好一事,就是出錯時告知使用者,發生了什麼事
你的論點是對的,但這個論點是不該建立在ajax上的。
你說的變數問題,大多都是人為的因素。而不是程式本身的問題。
你並不能怪罪於它身上。
ajax本身是存在可能失敗的情況,且這個失敗來源並非來自程式且無法控制。這時工程師得要決定的是,要忽視這個運行,然後下次再運行。還是就直接停止運行。
這兩種情況,得視應用的運行來決定。並沒有一定性哪邊比較好及哪邊比較不好。
一切的決定在於工程師的身上,畢竟前端有個很大的問題。使用者並非是工程師。在某些情況下是不能回報任何錯誤給其它人知道。
我上面的寫法採用了
console.log(XMLHttpRequest.responseText);
就是不將其直接顯示而回報於console上。
在這每秒請求的情況下。一般並不需要用alert之類的視窗。
這一秒拿不到,下一秒再拿就好。
當然,其實安全點我會用個時間計次。超過多久一直沒請求到的。我會將其計時器停止。但這已經是提外話了。