2016-04-07 11 views
1

私はいくつかの.get()を集める簡単なサービス方法を持っています。私は結果の一部しか持っていないので、 "印刷"の部分にいくつかの問題があります。最後にのみ結果を取得するためにメソッドをチェーンする方法はありますか?

私がやっていることは次のとおりです。

var service = function() { 
    var players = []; // will hold 100 objects 

    var getMembers = function(id) { 
    $.get(url, function(data) { 
     for(i=0; i<data.length; i++) { 
     var p = data[i]; 
     // get more info for this member 
     getMemberDetails(p.member_id); 
     // put the current data into the players 
     players.push(p); 
     } 
    }); 

    calculateAndPrint(); 
    }; 

    var getMemberDetails = function(id) { 
    $.get(url, function(data) { 
     var result = $.grep(players, function(e){ return e.member_id == id; }); 
     if (result.length == 0) { /* not found */ } 
     else if (result.length == 1) { 
     // push new data to player object 
     result[0].details = data; 
     } 
    }); 
    }; 

    var calculateAndPrint = function() { 
    for(i=0; i<players.length; i++) { 
     var p = players[i]; 
     console.log(p); 
    } 
    }; 
})(); 

、これは動作しません、私はcalculateAndPrintに達したとき、detailsがさえまだ設計されていないよう...

ので、私は$.Deferred()と試してみました私が持っている問題は、getMemberDetailsメソッドを延期すると、その呼び出しにはすでにdeffer呼び出し(.get())が含まれており、同じ問題に戻っているということです。

oに最適なオプションは何ですか? 100回の呼び出しがすべて行われた後に、calculateAndPrintを実行しますか?

それは十分に簡単そうですが、私はちょうど空白だ:/

+1

カウンタをインクリメントして100に達したら、 'getMemberDetails'コールバック内でその関数を実行してください – Hacketo

+2

このデータに対して100 + 1のHTTPリクエストを行いますか? 1回のコールに詳細を取得するために100回のリクエストすべてをバッチすることはできませんか? –

+0

あなたはidを使っていて、 'getMembers()'を呼び出す方法は? – itzmukeshy7

答えて

3

あなたが約束を使用する場合、これはかなり簡単なはず:

var service = function() { 
    var getMembers = function(id) { 
     return Promise.when($.get("some service url")) 
      .then(function (data) { 
       return Promise.all(data.map(getMemberDetails)); 
      }); 
    }; 

    var getMemberDetails = function(player) { 
     return Promise.when($.get("some service Url?id=" + player.member_id)); 
    }; 

    var calculateAndPrint = function(players) { 
     players.forEach(function (player) { 
      console.log(player); 
     }); 
    }; 

    return { 
     getMembers: getMembers, 
     calculateAndPrint: calculateAndPrint 
    }; 
})(); 

service.getMembers().then(function (players) { 
    service.calculateAndPrint(players); 
}); 
+0

...なぜ私は' $ .Deferred () '代わりに?私は 'service.getMembers()'を呼び出して一度にすべてを取得しようとしていました:) – balexandre

-1

あなただけのすべてのアヤックスがあなたを呼び出すための繰延オブジェクト$.deferredを作成することができます&を作成し、calculateAndPrint()メソッドを実行する前に、すべての遅延ジョブが完了するまで待ちます($.when)。


は仕組み:

  • は、すべてのAJAX呼び出し$.deferred &リターン約束オブジェクト.promise()のための繰延オブジェクトを作成します。
  • ajax呼び出しが成功したかどうかによって、応答データ.resolve(responseData)で解決するか、エラーデータ.reject(errorData)で拒否します。
  • ステップ1から返されたオブジェクトを約束し、完了したら、calculateAndPrint()メソッドを呼び出して、すべてのajax呼び出しを監視します。
  • 任意のajax呼び出しの場合、上記のロジックのほとんどはforループで呼び出され、遅延呼び出しのそれぞれがdeferredCalls配列にプッシュされる点を除き、ほとんど同じです。

注:あなたの作るAjaxの呼び出しは、あなたがすぐにバックグラウンド動作について知らさ&保管ユーザーの応答を取得しないため、常に優れたユーザーエクスペリエンスの記号であるとき、私はいくつかのローダ/スピナー画像を表示するようお勧めします。

JSコード:

/* utils */ 
var $ul = $('ul'); 

function msg(text) { 
    $ul.append('<li>' + text + '</li>'); 
} 

/* functions */ 
function asyncThing1() { 
    var dfd = $.Deferred(); 
    setTimeout(function() { 
    msg('asyncThing1 seems to be done...'); 
    dfd.resolve('banana'); 
}, 1000); 
return dfd.promise(); 
} 

function asyncThing2() { 
    var dfd = $.Deferred(); 
    setTimeout(function() { 
    msg('asyncThing2 seems to be done...'); 
    dfd.resolve('apple'); 
    }, 500); 
    return dfd.promise(); 
} 

function asyncThing3() { 
    var dfd = $.Deferred(); 
    setTimeout(function() { 
    msg('asyncThing3 seems to be done...'); 
    dfd.resolve('orange'); 
    }, 1500); 
    return dfd.promise(); 
} 

/* do it */ 
$.when(asyncThing1(), asyncThing2(), asyncThing3()).done(function(res1, res2, res3) { 
    msg('all done!'); 
    msg(res1 + ', ' + res2 + ', ' + res3); 
}); 

Live Demo @ JSFiddle


任意繰延通話Original SO Post

//Push all arbitrary ajax calls to deferred array 
var deferreds = []; 
function getSomeDeferredStuff() { 
    var i = 1; 
    for (i = 1; i <= 10; i++) { 
     var count = i; 
     deferreds.push(
     $.post('/echo/html/', { 
      html: "<p>Task #" + count + " complete.", 
      delay: count 
     }).success(function(data) { 
      $("div").append(data); 
     })); 
    } 
} 


// define a extension method for $.when for creating/managing deferred 
// objects for every ajax call 
if (jQuery.when.all===undefined) { 
    jQuery.when.all = function(deferreds) { 
     var deferred = new jQuery.Deferred(); 
     $.when.apply(jQuery, deferreds).then(
      function() { 
      var deferredObjs= function (arguments) { return deferreds.length > 1 ? $.makeArray(arguments) : [arguments]; } 
      deferred.resolve(deferredObjs); 
      }, 
      function() { 
      deferred.fail(deferredObjs); 
      }); 

     return deferred; 
    } 
} 

//passing the deferred calls array to $.when 
$.when.all(deferreds).then(function(objects) { 
    //process when all deferred objects compelted 
    console.log("Resolved/rejected objects:", objects); 
}); 

Working example for arbitrary ajax calls @JSFiddle

+0

OPの質問は、あとで任意の(つまりあらかじめ決められていない)数の非同期操作を待つことです別の非同期操作を実行します。あなたの答えは、特定の数の並列操作を待つ方法を示しているので、OPの質問には答えません。 – JLRishe

+0

これは、遅延呼び出しを行い、すべてが完了したときに通知を受け取る構文です。任意の遅延呼び出しを行うには、ループ内に遅延配列を作成し、その遅延配列を '$ .when.apply'に渡す必要があります、何も多くの変更は、任意の遅延呼び出しを行うときに上記のソリューションに変更されています。私はより良い理解のために私は答えを編集します。 – dreamweiver

関連する問題