navigator.serviceWorker.controller.postMessage为null,但仅在第一页加载时

时间:2019-12-30 15:51:57

标签: javascript service-worker

在第一页加载(清空IndexDB,缓存并注销服务工作程序之后)或没有缓存的重新加载(Ctrl + F5)时,出现以下错误:

Uncaught (in promise) TypeError: Cannot read property 'postMessage' of null

此错误不断出现在发送给服务人员的所有其他帖子消息中。直到我再次重新加载页面(使用缓存)。这不是比赛条件。首次加载页面时,出现了某些问题。

我就是不明白。有什么提示吗? Google没有提出任何建议。

导致它的代码如下:

const loadUUID = (callback, storename, data) => {
    let request = window.indexedDB.open(DBN, DBN_VERSION), db, tx, store, index;

    request.onerror = e => {
        console.log('request.onerror');
        console.log(e);
    };

    request.onsuccess = e => {
        db = request.result;
        tx = db.transaction('uuid', 'readonly');
        store = tx.objectStore('uuid');
        let cursor = store.openCursor(null, 'next');
        var mostRecent = null;

        cursor.onsuccess = e => {
            if (e.target.result) {
                mostRecent = e.target.result.value.uuid;
            }
        };


        tx.oncomplete = e => {
            db.close();
            if (data) {
                data.uuid = mostRecent;
                //navigator.serviceWorker.controller.postMessage(data);
                navigator.serviceWorker.ready.then(serviceworkerRegistration => {
                    console.log('within ready');
                    return serviceworkerRegistration.pushManager.getSubscription();

                })
                .then(subscription => {
                    if (!subscription) {
                        console.log('subscription MISSING');
                    }
                    console.log('within then of subscription');
                    navigator.serviceWorker.controller.postMessage(data); //line triggering the error

                });
            } else {
                callback(mostRecent);
            }
        };
    };
    request.onupgradeneeded = e => {
        let db = request.result;
        STORES.forEach(storename => {
            if (!db.objectStoreNames.contains(storename)) {
                db.createObjectStore(storename, {autoIncrement: true});
            }
        });
    };
};

注释掉的行会引起完全相同的问题。我认为这可能是比赛条件,SO上的另一则帖子建议等待SW准备就绪。但这对我的情况没有帮助。

1 个答案:

答案 0 :(得分:0)

我刚刚找到了一种解决方法,但是会对理解为什么这样做很有兴趣。

如果控制器不可用,我只是重新加载页面。实际上,这听起来像是Chrome中的错误,但是我不确定是否错过了某些事情。

        tx.oncomplete = e => {
            db.close();
            if (data) {
                data.uuid = mostRecent;
                if (!navigator.serviceWorker.controller) {
                    window.location.reload(false);
                } 
                navigator.serviceWorker.controller.postMessage(data);
                //if(callback) callback(storename, data);
            } else {
                callback(mostRecent);
            }
        };