簡體   English   中英

JavaScript 遞歸 setTimeout() 幾個小時后無法正常工作

[英]JavaScript recursive setTimeout() not working correctly after few hours

在我的 web 應用程序中,我使用遞歸 setTimeout() 每秒調用一次 function(見下文)。

function test() {
    console.log('test');
    setTimeout(test, 1000);
}

test();

它運行良好,但大約 6 小時后,它每隔 3 秒左右調用一次 test() function。 (setInterval() 也有同樣的問題)

該程序需要每天 24 小時運行,並且必須每秒更新一次。 任何想法如何解決這個問題。

這是完整的代碼:

function updateDateTime() {
    var now = new Date();
    
    /* Date */
    var woy = moment(now).format('W');
    var dow = now.getDay();
    var d = now.getDate();
    var m = now.getMonth();
    var y = now.getFullYear();
    document.getElementById('date_day').innerHTML = daysOfWeek[dow];
    document.getElementById('date').innerHTML = d + ". " + monthsOfYear[m] + " " + y;
    document.getElementById('date_week').innerHTML = "KW " + woy;

    /* Time */
    var h = now.getHours();
    var m = now.getMinutes();
    var s = now.getSeconds();
    m = checkTime(m);
    s = checkTime(s);
    
    /*if(odd)*/
        $("#time_colon").css('visibility', 'visible');
    /*else
        $("#time_colon").css('visibility', 'hidden');
    odd = !odd;*/
    
    document.getElementById('time_h').innerHTML = h;
    document.getElementById('time_m').innerHTML = m;
    document.getElementById('time_s').innerHTML = s;
    
    /* Clock */
    drawClock(now);
    
    setTimeout(updateDateTime, 1000 - moment().milliseconds() + 50);
}

function checkTime(i) {
  if (i < 10) {i = "0" + i};
  return i;
}

還有一些其他功能應該每 15 分鍾更新一次,使用 Ajax 請求,如下所示:

function updateNews() {
    var xmlhttp = new XMLHttpRequest();
    var url = "newsapi";
    xmlhttp.onreadystatechange = function() {
        if (this.readyState == 4 && this.status == 200) {
            document.getElementById('news').innerHTML = '';
            var news = JSON.parse(this.responseText);
            for(e in news){
                data = news[e];
                document.getElementById('news').innerHTML += '<span class="mx-3">'+data.title+'</span>';
                if(e < news.length) {
                    document.getElementById('news').innerHTML += ' &middot; ';
                }
            }
        }
    };
    xmlhttp.open("GET", url, true);
    xmlhttp.send();
    
    setTimeout(updateNews, 1800*1000);
}

我還使用代碼來禁用 chrome 瀏覽器的屏幕睡眠模式:

if ('wakeLock' in navigator) {
    // Screen Wake Lock API supported 🎉
    // The wake lock sentinel.
    let wakeLock = null;
    
    // Function that attempts to request a screen wake lock.
    const requestWakeLock = async () => {
        try {
            wakeLock = await navigator.wakeLock.request();
            wakeLock.addEventListener('release', () => {
                console.log('Screen Wake Lock released:', wakeLock.released);
            });
            console.log('Screen Wake Lock released:', wakeLock.released);
        } catch (err) {
            console.error(`${err.name}, ${err.message}`);
        }
    };
    
    // Request a screen wake lock…
    requestWakeLock();
}

如果您需要更多信息,請寫評論。

新更新:今天早上我看到新聞數據沒有更新,因為我的服務器崩潰了,但時間在 12 小時左右后仍然正確。 但是 4 小時后,在我重新啟動服務器和時鍾后,時間偏移了 2 秒。 所以我猜setTimeout的偏移量取決於其他超時中的Ajax請求。

這是我的結果列表:

| 超時值 | 設備 | 偏移 | 瀏覽器 |
| 1000 - moment().milliseconds() + 50 | 拉斯皮 | 大約 4-6 小時后 2 秒 | 鉻 & firefox |
| 1000 - moment().milliseconds() + 50 | 拉斯皮 | 沒有偏移但沒有工作 ajax 請求 | 鉻 |
| 1000 | 拉斯皮 | 大約 4-6 小時后大約 2 秒 | 鉻 & firefox |
| 500 | 拉斯皮 | 大約 4-6 小時后大約 2 秒 | 鉻 & firefox |

我解決了這個問題。

您只需在 Ajax 請求完成時調用 setTimeout() 事件。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM