2011-07-05 22 views
1

我使用IndexedDB,Web SQLWeb Storage在客戶端上存儲一些數據(或者在客戶端不支持任何存儲的情況下回退到AJAX)。加載頁面時,我想顯示商店中的一些數據。但是當DOM準備就緒時,我無法顯示數據,因爲商店可能沒有準備好,並且當商店準備就緒時我無法顯示數據,因爲DOM可能沒有準備好。如何激發取決於2(或更多)條件的JS事件

很明顯,我可以實現一些條件,檢查由dom和商店設置的標誌,或者我可以使用超時但看起來馬虎(如果超過2個條件需要滿足,將不能很好地擴展)。是否有一種「良好」的方式來處理這種情況?我寧願使用跨瀏覽器解決方案(例如watch將不起作用)。的情況

例子:

// FooServiceFactory decides which storage method to use based on 
// what the browser allows and returns a new instance of the 
// implementation and starts initializing resources. 
var fooService = FooServiceFactory.getInstance(); 

// DOM is ready 
window.onload = function() { 

    // fooService may not be ready yet depending on whether 
    // storage has already been setup or if resources need to 
    // be retrieved from the server. But I don't want this calling 
    // JS to know about that. 
    fooService.getAllFoo(request, function(response, status) { 
     // do something with response 
    }); 
}; 

注:我接受我自己的答案,現在,但我仍然是開放的處理這個更好的方法。

+1

爲什麼你認爲檢查條件標誌是否兩者都準備好是sl?不馴?這對我來說似乎相當合乎邏輯。 – Matt

+0

@Matt,我的存儲隱藏在服務層後面。雖然肯定會有效,但有標誌會破壞[封裝](http://en.wikipedia.org/wiki/Encapsulation_%28object-oriented_programming%29)。我不希望該服務知道DOM,並且我不希望調用JS知道它必須設置的全局變量,如果我可以幫助的話。 –

+0

@Matt,我用一個例子更新了我的問題。 –

回答

1

由於某些存儲(Web存儲和IndexedDB同步API)不是異步的,因此並不總是需要跟蹤這一點。最好讓服務實現自己處理它。

一種方法是在商店準備就緒後,讓實現對呼叫排隊並執行它們。這對於一些客戶來說尤爲重要,這些客戶會在用戶準備好之前讓用戶「允許」該店,這可能需要無限期的時間。這裏是一個如何處理IndexedDB實現的例子。

var FooServiceIndexedDB = function() { 
    var db = null; 
    var queue = []; 
    var dbRequest = window.indexedDB.open("footle", "All kinds of foo"); 

    var initStore = function() { 
     // Misc housekeeping goes here... 
     if (queue.length > 0) { 
      // Things to do if there are queued functions 
      for (var i = 0; i < queue.length; i++) { 
       queue[i](); // Run queued function 
      } 
     } 
    }; 

    dbRequest.onsuccess = function(dbRequestEvent) { 
     db = dbRequestEvent.target.result; 
     if (db.getVersion() != "1.0") { 
      db.setVersion("1.0").onsuccess = function(versionEvent) { 
       // Create stores/indexes 
       initStore(); 
      }; 
     } else { 
      initStore(); 
     } 
    }; 

    // Public accessor 
    this.getAllFoo = function(request, callback) { 
     _getAllFoo(request, callback); 
    }; 

    // Private accessor 
    var _getAllFoo = function(request, callback) { 
     if (db == null) { 
      // This method was called before the store was ready 
      queue.push(function() {_getAllFoo(request, callback);}); 
      return; 
     } 

     // Proceed getting foo 
    }; 
}; 
1

我通常在做異步的東西時互相依賴。

var running = 0; 

function fire(){ 
    running++; 

    //fire ajax bind callback 

} 

function callback(data){ 
    //do some stuff for this request 
    if(--running == 0){ 
    //do special stuff that relies on all requests 
    } 
} 

兩個請求返回同一時間的可能性,並且都將if-子句評估爲true幾乎爲零。

+0

「兩次請求同時返回的可能性以及將if子句評估爲真的機率爲零」。事實上,我認爲這是不可能的。 AFAIK,雖然請求可能在他們自己的線程中,但是這些線程在瀏覽器執行您的JavaScript之前是同步的。 – Ian

+0

用一個例子說明了我的問題。雖然這確實會工作99.999999%的時間(@Ian,它不是100%線程安全的,儘管我願意忍受0.000001%的誤報),但我主要關心的是break封裝。這項服務可以在任何頁面上調用,所有這些都需要知道這個全局變量。我可以看到它對我或同事來說成爲一個維護問題。 –