从同步缓冲区解析indexeddb / localforage读取?

时间:2019-03-02 08:06:08

标签: javascript 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:-

  • A。保证显示“酒吧”

  • B。保证显示“未定义”

  • C。不确定

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

1 个答案:

答案 0 :(得分:2)

我在https://github.com/localForage/localForage/blob/master/src/drivers/indexeddb.js看了localForage indexedDB驱动程序。我看不到任何缓冲。因此,getItem没有什么可以从某个缓冲区中获取的。

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

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

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

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

因此,查看您的代码,setItem('foo', 'bar')启动一个读写事务,而getItem('foo')启动一个只读事务。在开始只读事务之前,您无需等待读写事务承诺包装器建立。

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

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

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

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

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

  

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

     

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

     

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