4

従来のコールバック パターンを使用していたリソース読み込み関数をリファクタリングして、代わりに jQuery Deferreds を使用しています。

この関数は、url の配列を取り、リソースごとに新しい Deferred オブジェクトを作成し、$.whenそれらを監視する Deferred オブジェクトを作成し、オブジェクトの promise を返し$.whenます。

メソッドの簡略化されたバージョンを次に示します。

theLib = {
    getResources : function(paths) {
        var deferreds = [];
        theLib.isLoading = true;
        $.each(paths, function(i, path) {
            // do something with the path, either using getScript
            // or making a new $.Deferred as needed
            deferreds.push(/* the deferred object from above comment */);
        });
        theLib.currentDeferred = $.when.apply(null,deferreds).always(function() {
            theLib.isLoading = false;
        });

        return theLib.currentDeferred.promise();
};

これはうまくいきます。

私の問題: 古いスクリプトでは、theLib.getResources()ユーザーのアクションまたはイベントに基づいて 1 つの呼び出しを行うだけでなく、ユーザーがアクションを実行していない (つまり、記事を読んでいる) 間にアプリケーションが「ストリーミング」するリソースのマスター リストも定義していました。 )。

これらのストリーミングされたリソースの一部は、ユーザーアクションを実行したときに手動で呼び出すことができるリソースと同じです。このスクリプトは、ロードされたものを追跡することで、リソースを 2 回ロードしないほどスマートでした。

また、追跡しtheLib.isLoadingます。その関数の冒頭は次のようになりました。

getResources : function(paths, callback) {
    if (theLib.isLoading) {
        settimeout(function() {
            theLib.getResources(paths, callback);
        }, 100);
    }
    theLib.isLoading = true;

promise オブジェクトを返す必要があるため、これはもうできません。

を確認できることを知っていtheLib.currentDeferred.isResolved()ます。$.whenその時点で解決されない場合:監視されているキューに遅延オブジェクトを追加するにはどうすればよいですか?

4

1 に答える 1

3

自分で解決策を見つけるために質問する必要があったと思います。基本的に、次のコードを の先頭に追加しましたgetResources

if ( ! theLib.currentDeferred.isResolved()) { return $.when(theLib.currentDeferred).always(function() { theLib.getResources(paths); }).promise(); }

上記は失敗でした。正しい解決策は、結果をパイプすることでした:

if ( ! theLib.currentDeferred.isResolved()) {
    return theLib.currentDeferred.pipe(function() {
        return theLib.getResources(paths);
    });
}
于 2011-06-05T14:36:56.920 に答える