2016-08-04 27 views
2

我正在创建一个使用IndexedDB和服务人员的离线第一个博客平台。这里的想法是,如果用户处于离线状态,并试图发送一个帖子 - 在后台发送它。这个项目是为我的毕业论文设计的,我一直在看一个星​​期左右的承诺 - 如果这是一个简单的错误,我很抱歉!服务工作者后台同步 - 拒绝承诺 - waitUntil没有重试吗?

从我在react/redux中的操作中,我发送成功的同步事件。

下面是我的同步事件处理程序代码

self.addEventListener('sync', function(event) { 
    if (event.tag == 'send_post') { 
    //const URL 
    console.log('sync from SW - send post'); 
    //this should try again if promise is rejected 
    event.waitUntil(
     openDatabase('Outbox').then((db) => { 
     return databaseGet('posts',db).then((posts) => { 
      return sendAllFromOutbox(posts) 
     }) 
     }) 

    ); 
    } 
}); 

下面的openDatabase - (IndexedDB的)

function openDatabase(name) { 
     return new Promise(function(resolve, reject) { 
     var version = 10; 
     var request = indexedDB.open(name, version); 
     var db; 
     request.onupgradeneeded = function(e) { 
      db = e.target.result; 
      e.target.transaction.onerror = reject; 
     }; 
     request.onsuccess = function(e) { 
      db = e.target.result; 
      console.log('OPENED DATABASE'); 
      resolve(db); 
     }; 
     request.onerror = reject; 
     }); 
    } 

下面是databaseGet

function databaseGet(type,db) { 
    return new Promise(function(resolve, reject) { 
    var transaction = db.transaction([type], 'readonly'); 
    var store = transaction.objectStore(type); 
    var request = store.getAll(); 
    request.onsuccess = function(e) { 
     var result = e.target.result; 
     resolve(result); 
    }; 
    request.onerror = reject; 
    }); 
} 

最后,下面是sendAllFromOutbox

function sendAllFromOutbox(posts) { 
    return fetch('https://stirapi.herokuapp.com/sendPost', { 
    headers: {'Content-Type': 'application/json'}, 
    method: "POST", 
    body: JSON.stringify(posts) 
    }) 
    .then((response) => { 
    console.log('response from SW sendAllFromOutbox', response); 
    }) 
    .catch((err) => { 
    console.log('error from SW sendAllFromOutbox',err); 
    }) 
} 

从我的理解,如果sendAllFromOutbox失败/拒绝 - 它应该再次被调用。但它似乎没有被调用 - 因此不会在后台发送。

如果你想看看我的回购 - 它在这里https://github.com/georgecook92/Stir

谢谢!

乔治

+1

这不是你的问题,只是一般的警告:混合IDB和承诺时要小心,他们并不总是一起打好。请参阅https://crbug.com/457409中的示例。 – dgrogan

+0

谢谢!你能再解释一下吗?我认为sendAllFromOutbox函数将控制函数是否应该被调用?这只是一个从以前的IDB调用中获取数据的获取?如果我误解了道歉,对承诺不感兴趣! –

+0

IDB和承诺比以前要好得多。请参阅https://jakearchibald.com/2015/tasks-microtasks-queues-and-schedules/ –

回答

1

这是下降到浏览器来决定何时失败的同步事件应该重试。此外,它不会无限重试,但您知道这是通过syncEvent.lastChancespec)的最后一次尝试。

看看上面的代码,databaseGet预计(type,db),但你怎么称呼它databaseGet('posts'),所以当你尝试的db访问属性是会抛出一个错误,这是不确定的。 Chrome的开发工具应该显示这一点,尤其是在“突发错误”方面。

的这里的想法是,如果用户处于脱机状态,并试图发个帖子 - 在后台

这是最好使用后台同步无论用户的当前状态的发送。当然,navigator.onLine会告诉你用户是否肯定离线,但如果onLine为真,用户仍然可能没有可靠的连接。

+0

谢谢! 我在网上使用了你的例子,并改变它去除全局数据库,并通过链。我必须复制一个旧版本的功能,道歉!它似乎仍然没有重试。完整的代码可在我的回购 - https://github.com/georgecook92/Stir/blob/master/sw.js 感谢您对所有请求使用同步的建议!感谢回应! –