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 需要执行请求时,它会发送请求并继续执行,继续执行其余代码。当请求完成时,回调被触发。

所以在你的代码中它会像这样工作:

  1. 变量的初始化
  2. While 循环条件检查。条件为真,所以进入循环体。
  3. 执行ajax请求。我们发送请求并继续。
  4. 再次检查条件。由于没有任何改变(请求没有任何时间完成),条件仍然成立。
  5. 等等。

最终,十几个请求中的一个可能会结束,修改returnArrayand plcontinue,但这可能需要很长时间,因为函数体中的内容基本上是无限(几乎)循环,它占用了大部分 CPU 资源。

解决方案是用递归代替迭代:不是在无限循环中迭代直到成功,您可以递归直到成功。删除 while 循环getLinksFrom并添加getLinksFrom()到 ajax 请求回调。

另一种方法是同步请求。它有一个特殊的标志。

于 2013-02-06T04:44:25.277 回答