Tampermonkey 脚本更新逻辑

问题描述 投票:0回答:1

我正在开发一个在远程计算机上连续运行并且需要更新的用户脚本。

但是,当脚本自动更新时,它需要重新加载页面来应用更新,所以我的脚本也在尝试预测更新何时发生,以便之后可以刷新页面。

事实证明这很困难:即使我将时间段设置为至少六个小时,脚本通常会在上次更新后更新七个或更长时间。

那么 uodates 的逻辑是如何工作的呢?是否有一个钩子或回调可以用来在更新后重新加载页面,以便应用它?或者您还有其他一些技巧可以更准确地预测脚本更新的时间吗?

这是我目前用来执行此操作的逻辑:

function monitorScriptUpdates() {
    informUserIfScriptUpdated();
    var updateTimerSet = false;

    var timer = setInterval(() => {
        if (updateTimerSet) {
            clearInterval(timer);
        } else {
            checkForUpdates();
        }
    }, 60000);

    function checkForUpdates() {
        getNewestScriptVersion().then((newestVersion) => {
            const actualScriptVersion = GM_info.script.version;

            if (actualScriptVersion >= newestVersion) {
                return;
            }

            const currentTimeInMs = Date.now();
            const scriptLastUpdatedMs = GM_info.script.lastModified;
            const msSinceTheLastUpdate = currentTimeInMs - scriptLastUpdatedMs;
            const sixHoursInMs = 21600000;
            const fiftyMinutesBuffer = 3000000;

            updateTimerSet = true;
            if (localStorage.getItem('updateAttempted')) {
                localStorage.removeItem('updateAttempted');
                console.log('Automatic update failed, possibly because the update period is set to more than 6 hours! Disabling update check.');
                return;
            }

            const timeUntilUpdateIsAvailable = (sixHoursInMs - (msSinceTheLastUpdate % sixHoursInMs)) + fiftyMinutesBuffer;
            console.log('New script version detected! Automatic update will be attempted on ' + new Date(Date.now() + timeUntilUpdateIsAvailable));
            setTimeout(() => {
                console.log('Update should be available if the update period is set to 6 hours. Reloading...');
                localStorage.setItem('updateAttempted', true);
                location.reload();
            }, timeUntilUpdateIsAvailable);
        });
    }

    function informUserIfScriptUpdated() {
        var lastRecordedVersion = localStorage.getItem('scriptVersion');
        var actualScriptVersion = GM_info.script.version;

        if (lastRecordedVersion && lastRecordedVersion != actualScriptVersion) {
            localStorage.removeItem('updateAttempted');
            console.log('Script updated successfully from version ' + lastRecordedVersion + ' to version ' + actualScriptVersion);
        }

        localStorage.setItem('scriptVersion', actualScriptVersion);
    }
}

谢谢, 杜桑

javascript tampermonkey userscripts
1个回答
0
投票
当选项卡未聚焦时,

setTimeout
setInterval
极其不可靠,因为浏览器为了节省资源会暂停非活动选项卡的JS执行。

因此,您应该使用

setTimeout
,而不是使用
Date.Now()
,检查当前时间,然后根据需要进行更新。像这样:

setTimeout(() => {
  console.log('Update should be available if the update period is set to 6 hours. Reloading...');
  localStorage.setItem('updateAttempted', true);
  location.reload();
}, timeUntilUpdateIsAvailable);

应替换为:

const nextUpdateTime = Date.now() + timeUntilUpdateIsAvailable;
setInterval(()=>{
   if (Date.now() >= nextUpdateTime){
        console.log('Update should be available if the update period is set to 6 hours. Reloading...');
        localStorage.setItem('updateAttempted', true);
        location.reload();
   }
}, 600000); // Every 10 minutes, we check if the time expired.
© www.soinside.com 2019 - 2024. All rights reserved.