当indexedDB被阻止时,应用程序应如何反应 [英] How should an app react when indexedDB is blocked

查看:79
本文介绍了当indexedDB被阻止时,应用程序应如何反应的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在另一个问题中,我被告知有关检测阻止事件和取消阻止事件的信息未取消阻止的打开(或删除),只是...已阻止.取消阻止后,将继续打开(或删除)."

I was told in another question about detecting block and unblock events that "A blocked open (or delete) is not canceled, just... blocked. Once unblocked the open (or delete) will proceed."

我想知道应用程序应该如何响应被阻止的事件,如果成功事件之后的路径最终仍然有可能出现,那么

I was wondering how an app should respond to a blocked event then, if it is possible that the path following a successful event will still occur, eventually.

如果我希望我的应用快速响应 并遇到被阻止的事件,我应该取消成功路径吗?通过路径,我指的是在成功打开数据库的情况下执行的一系列语句,函数调用和延续.

If I want my app to respond quickly, and encounter a blocked event, should I cancel the success path? By path, I am referring to the series of statements and function calls and continuations that are performed in the event of a successful opening of the database.

以前,我假设阻塞事件阻止了成功路径的继续.我已经编写了我的应用程序,以将被阻止的事件视为类似于错误,这意味着该操作无法继续进行,应该向错误报告,然后执行其他操作或返回到空闲状态.

Previously I assumed that the blocked event prevented the success path from continuing. I have written my app to treat a blocked event as analogous to an error, meaning the operation cannot continue, and should report back with an error, and go do something else or return to an idle state.

对我来说,问题是,如果成功事件最终可以继续进行,则意味着我在分叉,错误路径和成功路径都会进行评估,并且可能会导致某些不良行为.

The problem for me is that if the success event can eventually continue, then this means I am forking, and both the error path and the success path will evaluate, and will probably result in some unwanted behavior.

或者我最初的理解是正确的,并且我不必担心取消成功时发生的事情,因为如果发生阻塞的火灾,那么我可以安全地推断出成功不会.

Or is my initial understanding correct, and I do not need to worry about canceling the things that happen onsuccess, because if onblocked fires then I can safely infer that onsuccess will not.

执行以下操作确实很丑陋,但这是避免出现问题的唯一立即想到的方法.

It feels really ugly to do something like the following, but this is the only immediate thing that comes to mind as a way to avoid my problem.

var r indexedDB.open(...);
var wasPreviouslyBlocked = false;
r.onsuccess = function() {
  // Cancel the success if previously blocked
  if(wasPreviouslyBlocked) {
    return;
  }
  // Proceed as normal
  doNextThing();
};
r.onblocked = function() {
  wasPreviouslyBlocked = true;
};

是否有更好的方法来应对这种情况?

Is there a better way to react to this scenario?

推荐答案

对我来说,问题是,如果成功事件最终能够 继续,那么这意味着我在分叉,并且错误路径和 成功的道路将会评估,并且可能会导致一些 不良行为.

The problem for me is that if the success event can eventually continue, then this means I am forking, and both the error path and the success path will evaluate, and will probably result in some unwanted behavior.

那是正确的.

或者我最初的理解是正确的,所以我不必担心 取消成功发生的事情,因为如果发生阻塞的火灾 那么我可以安全地推断成功不会成功.

Or is my initial understanding correct, and I do not need to worry about canceling the things that happen onsuccess, because if onblocked fires then I can safely infer that onsuccess will not.

如有疑问,请尝试一下!您只需要几个标签和一个本地服务器即可.将日志记录添加到请求的blockedsuccessupgradeneeded处理程序以及连接的versionchange处理程序中.

When in doubt, actually try it! All you need are a few tabs and a local server. Add logging to the blocked, success, and upgradeneeded handlers for the request and the versionchange handler for the connection.

作为背景,想象一个选项卡打开数据库的v1:

As background, imagine one tab opens v1 of the database:

var r = indexedDB.open('db', 1);
r.onupgradeneeded = function(e) {
var db = r.result;
  // schema v1: has store s1
  db.createObjectStore('s1');
};
r.onsuccess = function(e) {
  window.db = r.result;
};

现在将打开第二个选项卡,并下拉想要进行升级的较新代码:

Now a second tab is opened and pulls down newer code that wants to do an upgrade:

var r = indexedDB.open('db', 2);
r.onupgradeneeded = function(e) {
  // schema v1: has store s1
  // schema v2: adds store s1
  var db = r.result;
  if (e.oldVersion < 1) {
    db.createObjectStore('s1');
  }
  db.createObjectStore('s2');
};
r.onblocked = function(e) {
  console.log('uh oh...');
};

您可以采取至少三种一般方法来应对升级受阻.

There are at least three general approaches you can take in response to a blocked upgrade.

  1. 具有旧"连接的计算机会监视versionchange事件,并立即关闭以解除阻止升级.
  2. 具有"blocked"事件的新"连接监视并通知用户关闭其他选项卡
  3. 对"blocked"事件进行新"连接监视,并忽略升级.
  1. Have "old" connections watch for versionchange events and close promptly to unblock the upgrade.
  2. Have the "new" connection watch for blocked events and notify the user to close the other tabs
  3. Have the "new" connection watch for blocked events and ignore the upgrade.

由于您对#3感兴趣,因此请按以下步骤操作:

Since you're interested in #3, here's how you'd pull it off:

var r = indexedDB.open('db', 2);
r.onupgradeneeded = function(e) {

  // If we ever saw a blocked event, abort this upgrade.
  if (r.was_blocked) {
    r.transaction.abort();
    return;
  }

  var db = r.result;
  if (e.oldVersion < 1) {
    db.createObjectStore('s1');
  }
  db.createObjectStore('s2');
};

r.onblocked = function(e) {
  // Record that we saw a blocked event so this upgrade
  // can be ignored.
  r.was_blocked = true;
};

这与您在wasPreviouslyBlocked尝试中最终得到的结果非常接近,但是代码中存在一个严重的错误:您不会中止升级,只是实际上并没有修改架构.因此,您将获得一个数据库,该数据库具有架构版本2,但没有对v2进行任何更改.如果数据库再次打开,它将已经是v2,因此升级不会触发,并且您将缺少预期的架构更改.

This is pretty close to what you ended up with in your wasPreviouslyBlocked attempt, but there's a critical bug in your code: you don't abort the upgrade, you just don't actually modify the schema. So you'll end up with a database with schema version 2 but without any of the changes from v2. If the database opens again it will already be at v2 so the upgrade won't fire and you'll be missing the schema changes you expected.

这篇关于当indexedDB被阻止时,应用程序应如何反应的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆