【问题标题】:IndexedDB - During upgrade force abort, but with PromisesIndexedDB - 在升级期间强制中止,但有承诺
【发布时间】:2021-07-21 03:23:18
【问题描述】:

我用了这个帖子:IndexedDB: upgrade with promises?

并在此处实现部分:https://stackoverflow.com/a/25565755/15778635

这可以满足我的需要。我遇到的问题是:

var newMigrationPromise = function (dbName, version, migration) {
    return newPromise(function (deferred) {
        var request = indexedDB.open(dbName, version);

        // NB: caller must ensure upgrade callback always called
        request.onupgradeneeded = function (event) {
            var db = request.result;
            newTransactionPromise(
                function () {
                    var syncUPStore = transaction.objectStore("syncUP");
                    var syncCountRequest = syncUPStore.count();

                    syncCountRequest.oncomplete = function (event) {
                        if (syncCountRequest.result > 0)
                            deferred.reject(syncCountRequest.result + " SyncUp Records exist, database upgrade aborted, keeping at current version.");
                        else {
                            //Good, continue with update
                            migration(db, request.transaction);
                            return request.transaction;
                        }
                    }
                })
                .then(function () { db.close(); })
                .then(deferred.resolve, deferred.reject);
        };

        request.onerror = function (ev) { deferred.reject(request.error); };
    });
};

我有一个 syncUP 对象存储,其中包含在用户上线时需要发送到服务器的数据。在这种特殊情况下,Service Worker 正在安装(因为它们上线并且在服务器上进行了更改)并且需要在允许 Service Worker 更新之前知道是否存在 syncUP 记录。如果它们确实存在,那么它需要中止安装,直到它为空。

如果我要在var syncCountRequest = syncUPStore.count(); 所在的位置抛出错误,则服务人员中止工作正常,并且数据库中止升级工作正常。

我的问题: 如何检查“syncUP”对象存储中是否有记录并且仍然使用我上面提到的实现?我曾考虑将逻辑转移到另一种方法,但我发现我遇到了同样的问题,即不知道如何处理拒绝/解决。我的 Promises 知识还可以,但还不足以靠我自己弄清楚。

【问题讨论】:

  • 您不能在 onupgradeneeded 处理程序中很好地使用嵌套的 Promise,因为您无法等待它们,并且您无法附加仅稍后执行的功能,因为可用于 upgradeneeded 处理程序的版本更改事务将超时。我会避免在 upgradeneeded 中使用 Promise。
  • 另一个stackoverflow link I included 有一个promise 的实现,用来做你说它不能做的事情。我的问题是解释它足以为我做这件事。它似乎取决于“延迟”功能来管理它,但我不知道如何根据我的需要重新使用它。
  • 该链接以毫无意义的方式使用承诺,主要只是作为语法糖。我发表评论是因为我现在再次告诉你,在 upgradeneeded 中使用 Promise 会遇到问题,最好避免使用它们。
  • 您是 100% 正确的,我面临的问题是管理 serviceworker 和 indexeddb 更改时,我的客户有离线数据的主要版本。我改变了如何处理这个问题的方法,到目前为止它似乎可以满足我的需要。但是,如果我可以在升级过程中对现有商店进行数据检查并中止交易,那么升级就会失败。那我会更快乐。
  • 你可以这样做。在需要升级时,如果您看到以前存在旧版本,那么您可以对操作数据的版本更改事务执行迁移请求。

标签: javascript promise service-worker indexeddb idbobjectstore


【解决方案1】:

一个匆忙的例子:

var request = indexedDb.open(...);
request.onupgradeneeded = function(event) {
  if(conditionShouldDoMigrationFromVersionXToNowIsTrue) {
    migrate(event.transaction);
  }
};

function migrate(versionChangeTransaction) {
  var store = versionChangeTransaction.objectStore('x');
  var request = store.getAll();
  request.onsuccess = function(event) {
     var objects = event.target.result;
     for (var object of objects) {
       // do some mutation to the object
       object.x++;
       // write it back
       store.put(object);
     }
  }; 
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-08-18
    • 2020-03-30
    • 2019-11-03
    • 2015-07-25
    • 2020-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多