微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

服务工作者“同步”操作在离线时是否有效?

如何解决服务工作者“同步”操作在离线时是否有效?

我有一个 PWA 项目,我将数据发送到服务器。在此过程中,如果用户离线,则数据存储在 indexedDb 中并注册同步标签。因此,当用户上线时,数据可以发送到服务器。 但是在我的例子中,当我们注册一个同步事件标签时,同步事件会立即执行,这意味着尝试在离线时将数据发送到服务器,这是行不通的。

我认为同步事件应该只在在线时触发,这里可能有什么问题?

当我尝试启用和禁用 chrome devtools 的离线选项时,Service Worker 的同步事件会相应地工作,并且在我的 android 手机中也能正常工作。

这就是我注册同步标签的方式

function onFailure() {
    var form = document.querySelector("form");

    //Register the sync on post form error
    if ('serviceWorker' in navigator && 'SyncManager' in window) {
        navigator.serviceWorker.ready
            .then(function (sw) {
                var post = {
                    datetime1: form.datetime1.value,datetime: form.datetime.value,name: form.name.value,image: form.url.value,message: form.comment.value
                };
                writeData('sync-comments',post)
                    .then(function () {
                        return sw.sync.register('sync-new-comment');
                    })
                    .then(function () {
                        console.log("[Sync tag registered]");
                    })
                    .catch(function (err) {
                        console.log(err);
                    });
            });
    }
}

这就是同步事件的调用方式

self.addEventListener('sync',function (event) {

    console.log("[Service worker] Sync new comment",event);
    if (event.tag === 'sync-new-comment') {
        event.waitUntil(
            readAllData('sync-comments')
                .then(function (data) {
                    setTimeout(() => {
                        data.forEach(async (dt) => {

                            const url = "/api/post_data/post_new_comment";
                            const parameters = {
                                method: 'POST',headers: {
                                    'Content-Type': "application/json",'Accept': 'application/json'
                                },body: JSON.stringify({
                                    datetime: dt.datetime,name: dt.name,url: dt.image,comment: dt.message,datetime1: dt.datetime1,})
                            };

                            fetch(url,parameters)
                                .then((res) => {
                                    return res.json();
                                })
                                .then(response => {
                                    if (response && response.datetimeid) deleteItemFromData('sync-comments',response.datetimeid);
                                }).catch((error) => {
                                    console.log('[error post message]',error.message);
                                })
                        })
                    },5000);
                })
        );
    }
});

解决方法

你提到

当我尝试启用和禁用 chrome devtools 的离线选项时,Service Worker 的同步事件会相应地工作,并且在我的 android 手机中也能正常工作。

所以我不确定哪个案例失败了。

你说得对,当浏览器认为用户在线时会触发同步,如果浏览器在同步注册时检测到用户在线,则会触发sync

在真正的可扩展 Web 风格中,这是一个低级功能,可让您自由地做您需要的事情。您要求在用户连接时触发一个事件,如果用户已经连接,则立即触发。然后,您监听该事件并执行您需要执行的任何操作。

此外,来自工作箱 documentation

支持 BackgroundSync API 的浏览器将在浏览器管理的时间间隔内代表您自动重播失败的请求,可能会在重播尝试之间使用指数退避。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。