2011-07-05 4 views
1

IndexedDB,Web SQLまたはWeb Storageを使用して、クライアントにデータを保存します(クライアントがストレージをサポートしていない場合はAJAXにフォールバックします)。ページが読み込まれると、ストアのデータが表示されます。しかし、DOMは準備ができていない可能性があるため、ストアが準備完了状態になっているときにデータを表示できません。2(以上)条件に応じてJSイベントを発生させる方法

明らかに、私はdomとstoreで設定されたフラグをチェックするいくつかの条件を実装することができます。タイムアウトを使用することもできますが、それはうんざりです(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

どちらも準備ができているかどうかの条件付きフラグをチェックするのが賢明ではないと思われるのはなぜですか?それは私にとっては論理的なようです。 – Matt

+0

@Matt、私のストレージはサービス層の背後に隠れています。それが間違いなく機能する間、フラグを持つことは[カプセル化]を破ります(http://en.wikipedia.org/wiki/Encapsulation_%28object-oriented_programming%29)。私はDOMについて知っているサービスを望んでおらず、私がそれを助けることができれば、それを設定しなければならないグローバル変数についてJSが知りたいとは思わない。 –

+0

@Matt、私は例で私の質問を更新しました。 –

答えて

1

一部のストレージ(Web StorageおよびIndexedDB Synchronous API)は非同期ではないため、これを常に把握する必要はありません。サービス実装がそれを単独で処理することをお勧めします。

1つの方法は、実装待ち行列を呼び出して、ストアが準備ができているときにそれらを実行することです。これは、ユーザが準備が整う前にストアを「許可」するようにするクライアントによっては特に重要になり、無期限に時間がかかる可能性があります。次に、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 
    } 
} 

2つの要求と同じ時間を戻ってくるとの両方の場合、句真の評価の可能性はほぼゼロです。

+0

"2つの要求が同時に戻ってくる可能性があり、if節をtrueに評価することはほぼゼロです。"実際、私は不可能だと思う。 AFAIKはリクエストが自分のスレッドにあるかもしれないが、ブラウザがあなたのJavaScriptを実行する前にそれらのスレッドが同期されている。 – Ian

+0

私の質問を例で明確にしました。これは本当に99.999999%の時間で動作しますが(@Ian、それは100%スレッドセーフではありませんが、0.000001%の偽陽性で喜んで生きていきますが)、私の主な関心はブレークカプセル化です。このサービスは、このグローバル変数について知る必要のある任意の数のページで呼び出すことができます。私はそれが自分自身や道を歩いている同僚のメンテナンスの問題になっているのを見ることができました。 –

関連する問題