从另一个选项卡获取有关 IndexedDB 更新的事件
Getting events on IndexedDB updates from another tab
如果我在多个选项卡中打开了 IndexedDB
数据库,我可以在不重新加载的情况下跟踪所有选项卡上的数据更改吗?
没有内置的方法可以单独使用 IndexedDB 来做到这一点。您基本上有两个选择:
以一定的频率轮询 IndexedDB 并检查新值
使用其他一些交叉表通信方式发送一个信号,表明您需要从 IndexedDB 检查新值。例如 localStorage(当发生变化时发出交叉表事件)或 BroadcastChannel(专为交叉表通信而设计,但没有完美的跨浏览器支持)。
为了扩展 dumbmatter 的回答,下面是我如何使用 BroadcastChannel 实现的。如果您想要获得更多支持,我建议您使用 postMessage 而不是 BroadcastChannel。
function putThing(db, channel, thing) {
return new Promise(function(resolve, reject) {
const transaction = db.transaction('things', 'readwrite');
transaction.oncomplete = function(event) {
const message = {operation: 'updated', id: thing.id};
channel.postMessage(message);
resolve();
};
transaction.onerror = function(event) {
reject(event.target.error);
};
const store = transaction.objectStore('things');
store.put(thing);
});
}
// In tab where operation occurs
const db = await open(...);
const channel = new BroadcastChannel('myChannel');
await putThing(db, channel, thing);
channel.close();
db.close();
// In other tab where you want observation of changes
const channel = new BroadcastChannel('myChannel');
channel.onmessage = function(event) {
const message = event.data;
console.log('A message occurred', message);
};
几点:
- 频道无法向自己广播,所以它自己的同标签消息监听器函数将不会收到它的消息。但是,您可以在同一个选项卡上创建多个具有相同频道名称的频道实例,如果您需要该功能,每个频道都将收到其他频道的消息。
- 频道应该是短暂的,所以完成后关闭频道。但是,这也可能是您希望频道在页面打开时保持打开状态的情况
- 频道消息遵循与在数据库中存储对象类似的限制,例如您只能传递简单的 属性 值之类的数据,不能传递函数或自定义对象实例
如果我在多个选项卡中打开了 IndexedDB
数据库,我可以在不重新加载的情况下跟踪所有选项卡上的数据更改吗?
没有内置的方法可以单独使用 IndexedDB 来做到这一点。您基本上有两个选择:
以一定的频率轮询 IndexedDB 并检查新值
使用其他一些交叉表通信方式发送一个信号,表明您需要从 IndexedDB 检查新值。例如 localStorage(当发生变化时发出交叉表事件)或 BroadcastChannel(专为交叉表通信而设计,但没有完美的跨浏览器支持)。
为了扩展 dumbmatter 的回答,下面是我如何使用 BroadcastChannel 实现的。如果您想要获得更多支持,我建议您使用 postMessage 而不是 BroadcastChannel。
function putThing(db, channel, thing) {
return new Promise(function(resolve, reject) {
const transaction = db.transaction('things', 'readwrite');
transaction.oncomplete = function(event) {
const message = {operation: 'updated', id: thing.id};
channel.postMessage(message);
resolve();
};
transaction.onerror = function(event) {
reject(event.target.error);
};
const store = transaction.objectStore('things');
store.put(thing);
});
}
// In tab where operation occurs
const db = await open(...);
const channel = new BroadcastChannel('myChannel');
await putThing(db, channel, thing);
channel.close();
db.close();
// In other tab where you want observation of changes
const channel = new BroadcastChannel('myChannel');
channel.onmessage = function(event) {
const message = event.data;
console.log('A message occurred', message);
};
几点:
- 频道无法向自己广播,所以它自己的同标签消息监听器函数将不会收到它的消息。但是,您可以在同一个选项卡上创建多个具有相同频道名称的频道实例,如果您需要该功能,每个频道都将收到其他频道的消息。
- 频道应该是短暂的,所以完成后关闭频道。但是,这也可能是您希望频道在页面打开时保持打开状态的情况
- 频道消息遵循与在数据库中存储对象类似的限制,例如您只能传递简单的 属性 值之类的数据,不能传递函数或自定义对象实例