var在函数内没有接收到正确的值 - Javascript

时间:2016-12-08 17:45:20

标签: javascript jquery

我有一个名为 getQuotes()的函数,并且在它的末尾有一个 console.log(),它显示 currentQuote的正确值

function getQuote() {
      $.ajax({
            headers: {
              "X-Mashape-Key": "xxx",
              Accept: "application/json",
              "Content-Type": "application/x-www-form-urlencoded"
            },
            url: 'https://andruxnet-random-famous-quotes.p.mashape.com/?cat=movies',
            success: function(response) {
                  var r = JSON.parse(response);      
                  currentQuote = r.quote;
                  currentAuthor = r.author; 
                  console.log(currentQuote);             
            }
      });
};

重点是:当我调用 getFunction()(如下面的代码)时,显示我的变量 currentQuote console.log ,它没有收到正确的值,它仍然是一个声明的空字符串。我究竟做错了什么 ?

$(document).ready(function() {  
    var currentQuote='';
    var currentAuthor='';             
    getQuote();  
    console.log(currentQuote);        
});

2 个答案:

答案 0 :(得分:1)

因为getQuote()使用Ajax调用,所以当您调用getQuote()时,操作将异步进行。这意味着当getQuote()返回时,结果尚不可用。你可以通过提供一个回调函数作为getQuote()的参数并从success函数调用该函数来解决这个问题:

function getQuote(callback) {
    $.ajax({
        headers: {
          "X-Mashape-Key": "xxx",
          "Accept": "application/json",
          "Content-Type": "application/x-www-form-urlencoded"
        },
        url: 'https://andruxnet-random-famous-quotes.p.mashape.com/?cat=movies',
        success: function(response) {
              var r = JSON.parse(response);      
              callback(r.quote, r.author); // Report success to the caller
        }
    });
};

然后:

$(document).ready(function() {  
    getQuote(function(currentQuote, currentAuthor) { 
        console.log(currentQuote);
    });
});

这也消除了对全局currentQuotecurrentAuthor变量的需求。 (尽管你总是可以在回调中分配那些,如果其他地方需要这些值。)

<强>替代

您可以从Promise返回getQuote并修改Ajax调用以调用promise的resolve方法。这是在重复的帖子中接受的答案中描述的。

因为您正在使用jQuery,所以传递回调函数的另一种方法是返回ajax对象本身,它具有方便的done(result)属性:

function getQuote() {
    return $ajax({
        headers: {
          "X-Mashape-Key": "xxx",
          "Accept": "application/json",
          "Content-Type": "application/x-www-form-urlencoded"
        },
        url: 'https://andruxnet-random-famous-quotes.p.mashape.com/?cat=movies',
    });
}

然后使用:

$(document).ready(function() {
    getQuote().done(function(result) {
        if (result) {
            var r = JSON.parse(response);
            console.log(r.quote);
        }
    });
}};

这也在重复的线程中描述。有关详细信息,请参阅the docs for $ajax()

答案 1 :(得分:0)

您有两个不同的问题。

首先,从文档就绪回调中删除最终的console.log,并允许AJAX请求的成功回调为您进行记录。

其次,您有两组currentQuotecurrentAuthor变量:一组全局变量和一组本地作用于您的文档就绪回调的集合。您应该将每个变量明确定义为全局属性,以防止冲突:

$(document).ready(function() {  
    window.currentQuote = ''
    window.currentAuthor = ''             
    getQuote()        
});

function getQuote(cb) {
    $.ajax({
        headers: {
            "X-Mashape-Key": "xxx",
            Accept: "application/json",
            "Content-Type": "application/x-www-form-urlencoded"
        },
        url: 'https://andruxnet-random-famous-quotes.p.mashape.com/?cat=movies',
        success: function (response) {
              var r = JSON.parse(response)     
              window.currentQuote = r.quote
              window.currentAuthor = r.author 
              console.log(currentQuote)     
        }
    })
}

如果您想做的不仅仅是记录引号和作者,还有几种方法可以让您的生活更轻松:回调和承诺。

回调是一个函数,它作为参数传递给另一个(异步)函数,并在异步过程完成时调用一些“返回”值(如引号和作者)。在这里,我使用resolve作为回调函数。

$(document).ready(function() {            
    getQuote(function (quote, author) {
        // callback -- do stuff with `quote` and `author`
        console.log(quote, author)
    })
})

function getQuote(resolve) {
    $.ajax({
        headers: {
            "X-Mashape-Key": "xxx",
            Accept: "application/json",
            "Content-Type": "application/x-www-form-urlencoded"
        },
        url: 'https://andruxnet-random-famous-quotes.p.mashape.com/?cat=movies',
        success: function (response) {
              var result = JSON.parse(response)     
              resolve(r.quote, r.author)   
        }
    })
}

Promise是处理异步代码的一种更现代的方式,但默认情况下它们的支持也较少(这可以通过polyfill来解决)。承诺超出了本答案的范围,但如果您需要更多信息,我建议您查看the Promise page on the Mozilla Development Network