0

JavascriptでGoogleAnalyticsAPIを使用しています。

これらはリストの結果を取得するメソッドを提供し、実行が完了すると、結果を使用してコールバックメソッドを呼び出します。

次のようになります。

gapi.client.analytics.management.accounts.list().execute(handleAccounts);

..。

function handleAccounts(results) {
        if (!results.code) {
        if (results && results.items && results.items.length) {

// See this code below.

        } else {
            console.log('No accounts found for this user.')
        }
    } else {
        console.log('There was an error querying accounts: ' + results.message);
    }
}

一般的にこれは素晴らしいですが...私はすべての子アイテムのフラット化されたリストが必要なので、次のように呼び出し続けます:

 $.each(results.items, function (index, value) {

gapi.client.analytics.management.webproperties.list({ 'accountId': value.Id}).execute(handleWebproperties);
// and so on..
            })

問題は、いずれかのレベルで複数のアイテムがある場合、複数の非同期呼び出しが発生し、最終的なリストを取得するためにそれらがすべて終了したかどうかはわかりません。

何回の呼び出しが行われたかを追跡するために何かを書く以外に、その合計が戻ってくるのを待ちます。

それらがすべて完了したことを簡単に知るにはどうすればよいですか?

ありがとう。

要約すれば:

ユーザーは複数のアカウントを持つことができ、アカウントは複数のプロパティを持つことができ、プロパティは複数のプロファイルを持つことができます。

ユーザーのすべてのアカウントのすべてのプロファイルが必要です。

4

3 に答える 3

0

forkこれに対する以前の回答として書いた私の関数に基づいています: node.jsでの並列実行の調整。私はこのようにします:

var queryFunctions = []
$.each(results.items, function (index, value) {
    queryFunctions.push(function(callback){
        gapi.client.analytics.management.
            webproperties.list({ 'accountId': value.Id}).
            execute(callback);
    });
})

fork(queryFunctions,function(result){
    // This is the final callback, so do processing here
})

の実装forkは単純にこれです:

function fork (async_calls, shared_callback) {
  var counter = async_calls.length;
  var all_results = [];
  function makeCallback (index) {
    return function () {
      counter --;
      var results = [];
      // we use the arguments object here because some callbacks 
      // in Node pass in multiple arguments as result.
      for (var i=0;i<arguments.length;i++) {
        results.push(arguments[i]);
      }
      all_results[index] = results;
      if (counter == 0) {
        shared_callback(all_results);
      }
    }
  }

  for (var i=0;i<async_calls.length;i++) {
    async_calls[i](makeCallback(i));
  }
}

counterご覧のとおり、変数で行われた呼び出しの数を追跡するだけです。ただし、すべてが1つの関数にカプセル化されているため、ロジックを再利用できます。また、コードがより整頓されていると思います。

于 2012-10-08T05:13:55.040 に答える
0

jQuery Deferred機能を使用して、この種のことを行うことができます。基本的に、コールバックをDeferredオブジェクトでラップする場合は、を使用$.when(...)してそれらをすべてグループ化します。

このようなもの(あなたにとって最も意味のある正確な構造は、それをどのように使用しているかによって異なります。このコードは、各コールバックで特定のことを行う必要があり、すべてがいつ完了したかを知る必要があることを前提としています):

var promises = [];
$.each(results.items, function (index, value) {
    var deferred = new $.Deferred();
    gapi.client.analytics.management.webproperties.list({ 'accountId': value.Id}).execute(function(results) {
        handleWebproperties(results);
        deferred.resolve();
    });
    promises.push(deferred.promise());
    // and so on...
});

$.when.apply(this, promises).done(function() {
    alert("Everything is finished!");
});

私はブラウザウィンドウに直接コーディングしているだけなので、これは100%機能していない可能性があることに注意してください。:)

于 2012-10-08T05:24:00.280 に答える
0

これを解決する方法は、行った(または行う予定の)非同期呼び出しの数を追跡し、各応答でそのカウントのデクリメントを受け取り、最後の呼び出しが完了したかどうかを確認することです。1つの応答でエラーが発生し、正常に完了しない場合に備えて、堅牢なエラー処理を確実に行うことが重要です。

あなたはこれがオプションであることを知っているようで、なぜこれを追求しないのかは不明ですが、それはこれを解決する方法です。また、jQueryの延期を使用して、最後の実行がいつ行われたかを追跡することもできますが、それはライブラリを使用してカウントを行うだけです。基本的には同じです。

于 2012-10-08T04:52:52.390 に答える