2016-03-24 4 views
0

私はページ付けされたAPIを呼び出す関数を持っています。最初のページへの最初の呼び出しを行い、応答で返されたnext URLを使用して、後続のページへのリクエストを続けます。 nextnullになるまでこれを行います。私は、応答からデータ(都市名)を抽出し、これらをグローバル配列にプッシュしようとしています。複数のAPIリクエストからグローバル配列にプッシュ

私のコードは、現在、次のようになります。

ページ1

{ 
    "count": 105, 
    "next": "http://url.com/api/v1/cities/?page=2", 
    "previous": null, 
    "results": [ 
     { 
      "city_name": "Paris" 
     }, 
     { 
      "city_name": "Brussels" 
     } 
    ] 
} 

2ページ

:私はこのようになりJSONの2つのページを持っていると仮定すると

var results = []; 
function nextPage(url) { 
    if (!url) { 
     return; 
    } 
    $.getJSON(url, function(data) { 
     nextPage(data.next); 
     $.each(data.results, function (k, v) { 
      results.push(v.city_name); 
     }); 
    }); 
} 

nextPage('http://url.com/api/v1/cities/?page=1'); 
console.log(results); 

{ 
    "count": 105, 
    "next": null, 
    "previous": "http://url.com/api/v1/cities/?page=1", 
    "results": [ 
     { 
      "city_name": "Manchester" 
     }, 
     { 
      "city_name": "Curitiba" 
     } 
    ] 
} 

私は配列はこのように見えるように期待する:私はコンソールにresultsをログインしたときに、配列が空である、しかし

["Paris", "Brussels", "Manchester", "Curitiba"] 

。誰も助けることができますか?これ以上の情報が必要な場合はお知らせください。歓声

+0

見える。 nextPage()への2回目の呼び出しの直前にconsole.log()のデータを試してください。おそらく応答は期待通りではありません。 –

+1

nextPage is asynchronous - console.logは、データを取得してグローバル結果配列に格納する前に呼び出されています。 – thewatcheruatu

+0

javascript呼び出しが終了する前に 'results'配列データにアクセスしようとしています。あなたの 'console.log()'を '$ .each()'の中に入れてみてください。 'results'配列にデータが正しく入力されていることがわかります。 –

答えて

1

は、私はあなたがjQueryのを使用してこれを行うことをお勧め方法ですが約束:

function getCities(initialUrl) { 
    var results = []; 

    function nextPage(url) { 
     return $.ajax(url, {method: "POST", data: {json: src[cntr++]}}).then(function(data) { 
      $.each(data.results, function (k, v) { 
       results.push(v.city_name); 
      }); 
      if (data.next) { 
       return nextPage(data.next); 
      } else { 
       return results; 
      } 
     }); 
    } 

    return nextPage(initialUrl); 
} 

getCities('http://url.com/api/v1/cities/?page=1').then(function(results) { 
    console.log(results); 
}, function(err) { 
    // handle error here 
}); 

これは、あなたが機能し、その後呼び出し、その後からデータを取得することができます他のコードで使用する関数また、エラー処理パスも提供されます。

getCities関数は最初のURLを受け取り、結果の配列で解決される約束を返します。

内部nextPage()関数は次のURLをとります。私はそれが結果で得られるURLをテストして、次にそのURLを元に次の約束を連想させるか、最終的な結果を約束の最終的な達成価値として返します。

+0

@ sammy88888888 - 非同期操作のシーケンスとエラーの処理および伝播の約束をどのように使用するかを学ぶことを検討してください。これはES6で標準化され、非同期コードを書く現代的な方法です。あなたの質問とあなたが受け入れた答えのあなたのアプローチは、あなたの関数からデータを取得することはできませんし、エラー処理も行いません。両方とも、約束を正しく使うと実質的に無料になります。 – jfriend00

+0

回答を実装しようとしましたが、結果の最初のページだけが返されました。何か不足していますか? – sammy88888888

+0

@ sammy88888888 - 私はコードを正しくは持っていませんでしたが、今修正して簡略化しました。私はここにシミュレーションを構築しました:https://jsfiddle.net/jfriend00/s1hhxztv/それがすべて動作していることを確認してください。このアプローチは、それを呼び出すのに使うきれいなインタフェースを提供します。 – jfriend00

1

コメントと同様に、要求が完了する前にconsole.logが実行されます。代わりに、あなたはこのような何かしたいと思う:ここ

var results = []; 
function nextPage(url) { 
    if (!url) { 
     return; 
    } 
    $.getJSON(url, function(data) { 
     $.each(data.results, function (k, v) { 
      results.push(v.city_name); 
     }); 
     if(data.next){ 
      // There is a next page, continue: 
      nextPage(data.next); 
     }else{ 
      // You're done: 
      console.log(results); 
     } 
    }); 
} 

nextPage('http://url.com/api/v1/cities/?page=1'); 
+0

これはまさに私が探していたものです。ありがとう! – sammy88888888

関連する問題