当变量未定义时执行某些操作

时间:2018-04-06 17:19:17

标签: javascript asynchronous

我在用JavaScript编写的脚本中有一个函数(例如getContent();),它从页面获取XML内容,将其转换为JSON并将其存储在变量中(例如var resultsJSON;)。这个过程需要0.07秒才能完成,但对于脚本的其余部分来说仍然不够快。然后该脚本应该使用JSON的一部分。当我测试它时,控制台说变量resultsJSON是未定义的。我在函数中放了一个console.log来查看它实际获取XML的时间并将其存储在变量中。看起来代码是为了获取内容而发送的,然后在将内容添加到变量之前,脚本继续运行下一行代码。

我认为这个问题与同步代码和异步代码有关。我试图了解这一点,但我在理解它时遇到了一些麻烦,部分原因是我是JavaScript新手。在继续执行脚本的其余部分之前,如何让脚本等待变量不被定义?以下是我的脚本的示例:

var resultsJSON;
getContent();//gets XML from page, converts XML to JSON, makes resultsJSON = JSON
var item=resultsJSON.Item[0];
console.log(item);

最后两行需要在执行之前等待,直到resultsJSON有一个值。我该怎么做?

只是为了让你知道,我能够使用JQuery,但除非我绝对必须这样做,否则不愿意。

这是getContent函数的样子:

function getContent() {
    var xhttp = new XMLHttpRequest();
    xhttp.onreadystatechange = function() {
        if (this.readyState == 4 && this.status == 200) {
            resultsJSON = xml2json.fromStr(this.responseText);
            console.log(resultsJSON);
        }
    };
    xhttp.open("GET", 'getResults.php?'+queryURL, true);
    xhttp.send();
}

我删除了函数内部定义的变量,因为它们与问题无关。 queryURL变量是这些变量之一。此函数使用来自here的名为xml2json的脚本; xml2json在该脚本中定义。

2 个答案:

答案 0 :(得分:3)

这似乎不是一个同步与异步的问题,而是对JS出现问题的基本理解。

var resultsJSON;
getContent();//gets XML from page, converts XML to JSON, makes resultsJSON = JSON
var item=resultsJSON.Item[0];
console.log(item);

在上面的代码中,函数getContent();将立即执行,然后JS引擎将转到您尝试读取响应的下一行。但是,获取xml页面的调用可能还没有完成。您应该使getContent();返回您的值,而不是设置已声明的变量。 getContent();内部仅在呼叫完成后返回值。

var resultsJSON = getContent();//gets XML from page, converts XML to JSON, makes resultsJSON = JSON
var item = resultsJSON.Item[0];
console.log(item);

答案 1 :(得分:1)

以下是回调的快速演示,以及如何将其应用于您的问题。基本上,你发送你的getContent()函数的另一个函数的名称 - 然后一旦getContent()结算,你可以触发下一个函数继续你的代码:

var resultsJSON = {};

getContent( printResult );
//           ^Pass in the function name that you want
// to get executed after getContent() resovles

function getContent( callback ){
//                   ^ 'callback' is just a variable
// name at this point. This variable refers to the function
// passed in, to be called back later

// a timeout to mimic something that takes some time, in this
// case 3 seconds
  setTimeout( function(){
    resultsJSON.Item = [];
    resultsJSON.Item[0] = 'apple';
    callback();
    // ^invoke the callback function, in this case, it's calling
    // printResult();
  }, 3000 );
}

function printResult(){
  console.log(resultsJSON);
}

相关问题