0

私はかなり大きなjavascript関数に取り組んできましたが、最終的にそれが完了したと思ったとき、それは完全に機能しなくなりました。

ここにあります:

function getLinksFrom(title) {
  var returnArray = [],
      plcontinue = '',
      url = 'http://en.wikipedia.org/w/api.php?action=query&prop=links&titles=' + title + '&format=json&pllimit=500&plnamespace=0&callback=?';
  while (returnArray.length === 0 || plcontinue !== '') {
      if (plcontinue !== '') {
          url = 'http://en.wikipedia.org/w/api.php?action=query&prop=links&titles=' + title + '&format=json&pllimit=500&plnamespace=0&plcontinue=' + plcontinue + '&callback=?';
      }
      $.ajax({url: url, 
          dataType: 'json',
          success: function(data) {
              console.log(data);
              for (key in data['query']['pages']) {
                  links = data['query']['pages'][key]['links'];
              }
              for (var i = 0; i < links.length; i += 1) {
                  returnArray.push(links[i]['title']);
              }
              if (data.hasOwnProperty('query-continue')) {
                  plcontinue = data['query-continue']['links']['plcontinue'];
              } else {
                  plcontinue = '';
              }
          }
      });
  }
  return returnArray;
}

私の知る限り、ページがフリーズするだけなので、whileループでスタックしているに違いありません。しかし、ループごとにreturnArrayが大きくなり、plcontinueを何にも設定しないものでテストしています。

何がうまくいかないのか分かりますか?おそらく非同期ロードの何か、私はそれが初めてです。

編集:それで、私は有益なコメントを介して、ajaxが終了するのを待たずに何度も何度もループを繰り返して再開することを理解しました。どうすればそれを止めることができますか?

4

1 に答える 1

2

重要なのは、AJAXが非同期であるということです。つまり、JSがリクエストを実行する必要がある場合、JSはリクエストを送信して続行し、残りのコードを実行し続けます。リクエストが完了すると、コールバックが発生します。

したがって、コードでは次のように機能します。

  1. 変数の初期化
  2. whileループ状態チェック。条件は真なので、ループ本体に移動します。
  3. ajaxリクエストを実行しています。リクエストを送信して続行します。
  4. 再度状態を確認してください。何も変更されていないため(リクエストは完了する時間がありません)、条件は引き続き真です。
  5. 等々。

最終的には、数十のリクエストの1つが終了、変更returnArray、および変更されるplcontinue可能性がありますが、関数本体にあるのは基本的に無限の(ほぼ)ループであり、CPUリソースのほとんどを消費するため、これには長い時間がかかる可能性があります。

解決策は、反復を再帰に置き換えることです。成功するまで無限ループで反復する代わりに、成功するまで再帰することができます。whileループを削除し、ajaxリクエストコールバックにgetLinksFrom追加します。getLinksFrom()

もう1つのアプローチは、その要求を同期的に実行することです。それには特別な旗があります。

于 2013-02-06T04:44:25.277 に答える