proxy/override ServiceWorkerRegistration 函数的方法

Way to proxy/override ServiceWorkerRegistration function

我正在尝试代理 ServiceWorkerRegistration 对象的 showNotification 方法。以下是我现在的做法:

function swNotificationCallback(title, opt) {
    console.log("title", title);
    console.log("options", opt);
    return true
}

function createSWHandler(original) {
    return (title, opt) => {
        if (swNotificationCallback(title, opt)) {return original(title, opt)}
    }
}

navigator.serviceWorker.getRegistrations().then(val => val.forEach(sw => {
    if (!sw._showNotification) {
        // backup the old just in case
        sw._showNotification = sw.showNotification;
        sw.showNotification = createSWHandler(sw.showNotification);
    }
}));

调用 sw.showNotification 正确记录所有内容,但未显示任何通知并抛出此错误: Uncaught (in promise) TypeError: 'showNotification' called on an object that does not implement interface ServiceWorkerRegistration.

有什么办法可以解决这个问题吗?我认为可以使用代理,但我不确定如何重新分配已注册的服务工作者。

您需要在实例上调用该方法,而不是作为没有上下文的普通函数。使用 call:

function createSWHandler(original) {
    return function(title, opt) {
//         ^^^^^^^^
        if (swNotificationCallback(title, opt)) {
           return original.call(this, title, opt)
//                        ^^^^^^^^^^^
        }
    }
}

或者你可以

createSWHandler(sw.showNotification.bind(sw))