0

我在javascript中有一个函数,它应该返回一个由维基百科页面链接到的所有文章的数组,给定标题。

这里是:

function getLinksFrom(title, returnArray, plcontinue) {
  var url = 'http://en.wikipedia.org/w/api.php?action=query&prop=links&titles=' + title + '&format=json&pllimit=500&plnamespace=0&callback=?';
  if (!returnArray) {
      returnArray = [];
  }
  if (!plcontinue) {
    plcontinue = '';
  }
  if (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',
          async: false,
          success: function(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 = '';
              }
              console.log(returnArray);
              return getLinksFrom(title, returnArray, plcontinue);
          }
      });
  }
  console.log(returnArray);
  return returnArray;
}

当我运行这个函数并观察控制台时,console.log(returnArray); 行将我想要的内容放在控制台中。字符串数组。但这就是我感到困惑的地方。

我想将该 returnArray 存储在一个名为 links 的变量中。这是函数下方的那条线。

var links = getLinksFrom('United States');

但是链接最终并不等于之前记录的那个美妙的东西。相反,它包含一个对象数组,长度不正确。

这里发生了什么事?

4

1 回答 1

2

由于getLinksFrom是异步函数,当 JS 评估函数调用时,它会立即将结果写入links变量。但是那个时候returnArray是空的!

看一下图片:

在此处输入图像描述

它表明,returnArray在将其分配给links变量之后,并且很可能在使用此变量之后,推送到发生。

所以如果你使用异步代码,你不能只做a = b(). 通常在这种情况下人们使用回调:(b(function(a) { /* do something with a */ })参数是一种“成功”函数)。因此,您应该重写代码以使用回调异步工作。

但是你的代码还有一个问题:你永远不会停止自我调用。每次成功请求后,您都会发送另一个请求并且永不停止。也许,在多次请求之后,您将不再获得任何有用的数据,那么为什么要用无用的请求来打扰远程服务器和用户的网络呢?完成后不要进行递归。取而代之的是,您可以调用callback以通知您的函数调用者您已完成。

于 2013-02-06T08:25:10.643 回答