如何从indexedDB回调中安全地修改全局变量?

时间:2013-06-15 06:59:47

标签: javascript html5 asynchronous indexeddb

我正在开始一堆indexeddb操作,并希望它们能够增加一个计数器(并改变其他一些东西,但对于这个问题,只是假设它正在递增一个计数器)。我从IndexedDB specs知道它在不同的线程中运行回调(尽管有这样的措辞,但我不确定实现是否必须使用线程)。但AFAIK,JavaScript / HTML5没有任何保证线程安全的东西,所以我担心以下情况:

/* Sequence involved in incrementing a variable "behind the scenes" */
//First callback calls i++; (it's 0 at this point)
load r0,[i]  ; load memory into reg 0

//Second callback calls i++ (it's still 0 at this point)
load r1,[i]  ; load memory into reg 1

//First callback's sequence continues and increments the temporary spot to 1
incr r0      ; increment reg 0

//Second callback's sequence continues and also increments the temporary spot to 1
incr r1      ; increment reg 1

//First callback sequence finishes, i === 1
stor [i],r0  ; store reg 0 back to memory


//Second callback sequence finishes, i === 1
stor [i],r1  ; store reg 1 back to memory

(或类似的东西)

那么我的选择是什么?我可以在每个调用postMessage的回调中生成Web worker,并且侦听器会增加它吗?类似的东西:

increment.js (我们的工人代码)

//Our count
var count = 0;

 function onmessage(event)
 {
    count += event.data;
 }

main.js

//Our "thread-safe" worker?
var incrementer = new Worker( "increment.js" );

//Success handler (has diff thread)
req.onsuccess = function(event) {  

    ...finish doing some work...

    //Increment it
    incrementer.postmessage( 1 );
};

那会有用吗?或者web worker的onmessage是否仍会出现在回调的主题中?有没有办法让它成为全球线程?

1 个答案:

答案 0 :(得分:7)

在引用的文档中唯一提到的'thread'一词是IndexedDB API方法不会阻塞调用线程(这仍然不暗示这些方法在不同的线程中运行,但它只是说明了这些方法本质上是异步的,但没有提到任何回调将在不同的线程中运行。

此外,JavaScript本身是单线程的,因此您可以安全地假设回调将全部在同一个(“全局”)线程中运行,并且将按顺序调用,而不是同时调用。

因此不需要Web worker,您可以直接从回调本身增加全局变量:

req.onsuccess = function(event) {  
  count += event.data;
};