从同步缓冲区解析indexeddb/localforage读取? [英] are indexeddb/localforage reads resolved from a synchronous buffer?

查看:184
本文介绍了从同步缓冲区解析indexeddb/localforage读取?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

采用以下伪代码

localforageStore.setItem('foo', 'bar')
    .then(console.log('foo is persisted to disk')); 
localforageStore.getItem('foo')
    .then(v => console.info('foo is '+v));   // A, B or C? 

是console.info:-

Is the console.info:-

  • A.保证显示酒吧"

  • A. Guaranteed to display 'bar'

B.保证显示未定义"

B. Guaranteed to display 'undefined'

C.不确定

即即使对磁盘的写入是异步的,是否也可以从indexeddb和/或localforage内部的缓冲区解析同步读取?

i.e. even though the write to disc is async, will a synchronous read be resolved from a buffer internal to indexeddb and/or localforage?

推荐答案

我在

I took a look at the localForage indexedDB driver at https://github.com/localForage/localForage/blob/master/src/drivers/indexeddb.js. I do not see any buffering. Therefore, there is nothing for the getItem to grab from some buffer.

更具体地说,再次查看localForage源,我可以看到 setItem getItem 是围绕indexedDB事务的基本promise包装.那些包装器在事务完成时解析.这告诉我,indexedDB是控制非阻塞行为而不是localForage的原因.

More specifically, looking at the localForage source again, I can see that setItem and getItem are basic promise wrappers around indexedDB transactions. Those wrappers resolve when the transactions complete. This tells me that indexedDB is what controls the non-blocking behavior, not localForage.

因此,由于indexedDB负责,这意味着我们可以查看indexedDB的行为以帮助回答您的问题.我们正在发布两个交易,每个交易都有一个请求.第一个是来自 setItem 的读写事务,第二个是来自 getItem 的只读事务.

So, because indexedDB is in charge, this means we can look at indexedDB behavior to help answer your question. We are issuing two transactions, each with a request. The first is a readwrite transaction from setItem, and the second is a readonly transaction from getItem.

通常,交易可以重叠.例如,您可以同时运行100个只读事务.但是,读写事务会阻止其他事务,以确保数据完整性.读写事务不能重叠.

Ordinarily, transactions can overlap. For example, you can have 100 readonly transactions all running at the same time. However, readwrite transactions block other transactions in order to ensure data integrity. readwrite transactions cannot overlap.

由于您可以开除并忘记通话内容,因此这变得有些复杂.您可以同时初始化两个事务,而不必等到第二个事务完成才开始.请注意开始运行某项与实际将其视为运行之间的区别.

This gets complicated a bit by the fact that you can fire and forget call things. You can init two transactions at the same time, without waiting to start the second until after the first completes. Note the difference between starting to run something, and actually have it be considered running.

因此,查看您的代码, setItem('foo','bar')启动一个读写事务,而getItem('foo')启动一个只读事务.在开始只读事务之前,您不必等待读写事务承诺包装器安定下来.

So, looking at your code, setItem('foo', 'bar') starts a readwrite transaction, and getItem('foo') starts a readonly transaction. You are not waiting for the readwrite transaction promise wrapper to settle before starting the readonly transaction.

尽管这实际上是一种非阻塞方法,但从技术上讲,它仍在indexedDB层内进行阻塞,因为只读事务将阻塞(无限期地)等待同一对象存储上的先前读写事务解决.

While that is indeed a non-blocking approach on the surface, it is still technically blocking within the indexedDB layer, because the readonly transaction will block (wait, indefinitely) for the prior readwrite transaction on the same object store to settle.

这就是我认为引起混乱的原因.因为我们知道只读事务是在读写开始之后才启动的,所以我们知道只读事务在技术上总是会在读写事务之后才解决,因为它不可能在读写事务之前或同时解决.

And this is what I think causes confusion. Because we know the readonly transaction was started after the readwrite was started, we know that the readonly transaction will technically always resolve only after the readwrite transaction, because it cannot possibly resolve before it, nor at the same time as it.

因此,您可以说答案是A.因为只读事务必须等待读写事务完成.它在localForage承诺层是不确定的,但在indexedDB事务层是不确定的.

Therefore, you can say the answer would be A. Because the readonly transaction has to wait for the readwrite transaction to complete. It is indeterminate at the localForage promise layer, but determinate at the indexedDB transaction layer.

有关详细说明,请参见 https://www.w3.org/TR/IndexedDB-2/#transaction-construct

Look at the spec for some more technical explanation at https://www.w3.org/TR/IndexedDB-2/#transaction-construct

以下是相关部分(重点是我的部分):

Here is a relevant section (emphasis mine):

如果多个读/写事务正在尝试访问同一事务对象存储区(即,如果它们具有重叠的作用域),则交易首先创建的必须是可以访问的事务首先存储对象.由于之前的要求段落,这也意味着这是唯一具有以下条件的交易:访问对象库,直到交易完成.

If multiple read/write transactions are attempting to access the same object store (i.e. if they have overlapping scope), the transaction that was created first must be the transaction which gets access to the object store first. Due to the requirements in the previous paragraph, this also means that it is the only transaction which has access to the object store until the transaction is finished.

在读/写事务之后创建的任何事务都必须看到读/写事务写入的更改.因此,如果读/写创建了事务A,之后又是另一个事务B创建,并且两个事务具有重叠的作用域,那么B必须查看属于该对象存储库的任何对象存储库所做的任何更改范围重叠.由于上一段的要求,这也意味着B交易无权访问任何对象存储在该重叠范围中,直到A事务被完成.

Any transaction created after a read/write transaction must see the changes written by the read/write transaction. So if a read/write transaction, A, is created, and later another transaction B, is created, and the two transactions have overlapping scopes, then B must see any changes made to any object stores that are part of that overlapping scope. Due to the requirements in the previous paragraph, this also means that the B transaction does not have access to any object stores in that overlapping scope until the A transaction is finished.

通常来说,以上要求意味着任何交易哪个范围与读/写事务重叠,并且哪个是在该读写事务之后创建的,因此无法并行运行进行该读/写事务.

Generally speaking, the above requirements mean that any transaction which has an overlapping scope with a read/write transaction and which was created after that read/write transaction, can’t run in parallel with that read/write transaction.

这篇关于从同步缓冲区解析indexeddb/localforage读取?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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