2013-02-06 2 views
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'); 

그러나 링크가 이전에 기록 된 멋진 내용과 동일하지 않습니다. 대신, 올바른 길이가 아닌 객체의 배열을 포함합니다.

여기가 어떻게됩니까?

답변

2

이 비동기 함수이기 때문에 JS가 함수 호출을 평가할 때 즉시 결과를 links 변수에 씁니다. 그러나 그 시점에서 returnArray은 비어 있습니다!

는 그림을 살펴 보자 :

enter image description here

그것은 returnArray에 밀어 것은이 변수를 사용 후, 대부분의 links 변수에 할당하고 이후에 발생하는 것을 알 수있다.

비동기 코드를 사용하는 경우 a = b()을 수행 할 수 없습니다. 일반적으로이 경우 사람들은 콜백을 사용합니다 : b(function(a) { /* do something with a */ }) (인수는 일종의 "success"함수입니다). 콜백을 사용하여 비동기 적으로 작업하도록 코드를 다시 작성해야합니다.

하지만 코드에는 한 가지 더 많은 문제가 있습니다. 절대 자기 호출을 중지하지 마십시오. 성공한 요청이있을 때마다 다른 것을 보내고 절대 멈추지 마십시오. 어쩌면 몇 가지 요청을 한 후에 유용한 데이터를 얻을 수 없으므로 쓸데없는 요청으로 원격 서버와 사용자 네트워크를 왜 괴롭 히니까? 완료되면 재귀를 수행하지 마십시오. 그 대신에 callback으로 전화하여 기능 호출자에게 완료되었다는 사실을 알릴 수 있습니다.

+0

사진의 경우 :-) –