2

我正在创建一个利用 IndexedDB 和服务工作者的离线第一个博客平台。这里的想法是如果用户离线并尝试发送帖子 - 在后台发送。这个项目是为我的论文准备的,我只看了一个星期左右的 Promise - 如果这是一个简单的错误,我深表歉意!

从我在 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

谢谢!

乔治

4

1 回答 1

1

何时重试失败的同步事件由浏览器决定。此外,它不会无限重试,但您知道这是通过syncEvent.lastChance( spec ) 进行的最后一次尝试。

查看上面的代码,databaseGet期望(type,db),但您调用它,因此当您尝试访问未定义databaseGet('posts')的属性时会引发错误。dbChrome 的 devtools 应该会显示这一点,尤其是在“捕获错误时中断”。

这里的想法是如果用户离线并尝试发送帖子 - 在后台发送

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

于 2016-08-09T09:54:46.447 回答