2013-06-15 18 views
5

Wywołuję kilka akcji indexeddb i chcę, aby były w stanie zwiększyć licznik (i zmienić również inne rzeczy, ale na to pytanie, po prostu zakładam, że zwiększa licznik), gdy skończą. Wiem od IndexedDB specs, że uruchamia on wywołania zwrotne w różnych wątkach (chociaż mimo tego sformułowania nie jestem pewien, czy implementacje muszą używać wątków, czy nie). Ale AFAIK, JavaScript/HTML5 ma nic, co gwarantuje bezpieczeństwo wątek czegoś, więc boję się następującej sytuacji:Jak mogę zmienić zmienną globalną z callbacków indeksowanych DB?

/* 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 

(lub coś w tym kierunku)

Więc jakie są moje opcje? Czy mogę odrodzić pracowników sieci Web w każdym z wywołań zwrotnych, które wywołują postMessage, a słuchacz go zwiększa? Coś jak:

increment.js (kod naszego Robotniczy)

//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); 
}; 

Czy to działa? A może w trakcie wątku zwrotnego nadal będzie występował komunikat web worker? Czy istnieje sposób na to, aby znaleźć się w globalnym wątku?

Odpowiedz

7

Jedyną wzmianką o słowie "wątek" w przywoływanej dokumentacji jest to, że metody API IndexedDB nie blokują wywoływanego wątku (co nadal nie oznacza, że ​​metody są uruchamiane w osobnych wątkach, ale po prostu stwierdza że metody są z natury asynchroniczne), ale nie wspomina się o tym, że wywołania zwrotne będą w ogóle uruchamiane w różnych wątkach.

Sam skrypt JavaScript jest jednowątkowy, więc można bezpiecznie założyć, że wszystkie wywołania zwrotne będą uruchamiane w tym samym ("globalnym") wątku i będą wywoływane sekwencyjnie, a nie jednocześnie.

Więc nie potrzebują pracowników internetowych, można po prostu zwiększamy zmienną globalną bezpośrednio od samych wywołań zwrotnych:

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

Ale to ciągle używa słowa „asynchroniczny”, który zakłada rzeczy można zrobić poza kolejnością. '" 3.3.5 Kroki dla asynchronicznego wykonywania żądania "'. czy nie oznacza to, że mogą istnieć warunki wyścigu? Jak można zagwarantować, że coś, co jest asynchroniczne, nie będzie miało warunków wyścigu, jeśli nie jest to określone w specyfikacji? –

+1

@DonRhummy "warunki wyścigu" nie są rozwiązywane przez bezpieczeństwo wątków. Jeśli chcesz, aby operacje asynchroniczne utrzymywały ich kolejność lub przynajmniej kończyły się wynikami w kolejności, w której uruchamiasz te operacje, musisz mieć jakiś kod koordynujący (np. [Moduł asynchroniczny] (https: // github .com/caolan/async) może zapewnić); ale nadal nie polega to na wątkach lub prymitywnych operacjach. – robertklep

+0

Przepraszam, chodziło o warunki wyścigu w sensie, w jakim miałem w pierwotnym poście. Obawiam się, że naprawdę istnieją wątki i nie ma gwarancji, że wywołania zwrotne nie będą miały dostępu do niedziałających. –

Powiązane problemy