如何从$ .getJSON函数返回变量

时间:2015-07-03 11:31:41

标签: javascript jquery ajax json asynchronous

我的问题几乎与此问题相同:How can I return a variable from a $.getJSON function

Stack Overflow上还有其他一些重复内容,我已经通读了它们但尚未找到满意的答案。

我意识到$ .getJSON异步运行的事实,我一直在编写如下函数:

function getSharePriceAtDate(date) {
    $.getJSON(queryString, function(data) {
        $("#share-price-at-date").html(data.values[0][date]);
    });
}

这很好,例如,让我将数据从JSON源直接写入HTML文档(使用回调确保数据在写出之前已经收到)。

但是,这真的不是我想要做的......我希望能够从我的代码的其他部分调用getSharePriceAtDate()

例如:

function calcChangeInValue(date) {
    var output = currentSharePrice - getSharePriceAtDate(date);
    return output;
}

为此,我真的需要$ .getJSON来同步运行...我需要能够创建一个getSharePriceAtDate(date)函数,它实际上在功能上完成它所说的并从JSON源返回一个特定的值,而不是在回调中被迫打印到HTML。

我链接的问题中建议的解决方案是重写$.getJSON()作为$.ajax()的简写功能并设置async = false

这更符合我的要求,但Chrome控制台会发出以下警告:

  

主线程上的同步XMLHttpRequest因其对最终用户体验的不利影响而被弃用。如需更多帮助,请查看http://xhr.spec.whatwg.org/

在我的情况下,我只是抓取1个值,并且在这个例子中进行了测试,它确实不会以任何方式看到它有害......(这只是意味着我的代码会挂起,直到JSON请求回来了,但无论如何它都必须!异步或其他 - 我仍然需要这些数据进行计算。)

所以我认为在这种情况下async = false一定不是问题,但上面警告中的链接说:

  

工作人员之外的同步XMLHttpRequest正在从Web平台中删除,因为它对最终用户的体验产生了不利影响。 (这是一个需要很多年的漫长过程。)当JavaScript全局环境是文档环境时,开发人员不得为async参数传递false。强烈建议用户代理在开发人员工具中警告这种用法,并尝试在发生时抛出InvalidAccessError异常。

如果我使用async = false,我的代码似乎不会成为未来的证据。

Stack Overflow中有很多人在询问如何使用$.getJSON(),答案通常会告诉他们使用回调。

我想知道:

  1. $.getJSON()在此上下文中异步的优势是什么?
  2. 如何在函数中访问外部JSON数据 从JSON返回一个值? (即,我如何能够通过var price = getSharePriceAtDate()拨打电话,并在找到price时等待我的代码
  3. 编辑:我已经知道如何做getSharePriceAtDate(calculateChangeInValue);这样的代码我写的代码可以真正做到能够在特定日期经常打印股价,我希望有更好的方法

4 个答案:

答案 0 :(得分:2)

问题1:Async允许您从服务器获取数据而不会阻止整个UI。

问题2:使用承诺模式

function getSharePriceAtDate(date) {
    //for example, if the price was contained in a JSON response: {price:$1200}
    return $.getJSON(date).then(function(data) { return data.price; });
}

function calcChangeInValue(date1,date2) {
  return $.when(getSharePriceAtDate(date2),getSharePriceAtDate(date1)
   .then(function(price2,price1) {
      return price2-price1;
   });

}

calcChangeInValue(date1,date2)
 .then(function(change) {
   $(element).html(change);
 });

并且,对于记录,这也是网站上有关如何从AJAX调用返回值的所有其他问题的重复。

答案 1 :(得分:0)

您需要在某处保存异步响应,并且只在两个json文件到达后才执行计算。但正如亚当所说,如果你可以使用它们,最好使用promises。

答案 2 :(得分:0)

jquery中的所有$ .ajax都返回一个promise或者deferred。如果所有异步任务都已完成并按行动执行,则可以使用when()进行控制。

https://api.jquery.com/category/deferred-object/

https://api.jquery.com/promise/

https://api.jquery.com/jquery.when/

答案 3 :(得分:0)

这里简短的回答是:不,你不能。

更长的答案:看,这是Javascript的工作方式(一般情况下是事件驱动的代码)。

您不应该在事件驱动的环境中编写纯线性代码;它根本没有意义,并将导致进一步的问题。不要试图找出如何按照自己的方式去做,并学会接受平台所期望的做事方式。

不要尝试将返回值传回;而是将将使用该值的其余代码作为参数传递给初始调用。

所以你希望编写看起来像这样的代码......

var output = calcChangeInValue(date1, date2);
//code that does something with output...

相反,这样做:

calcChangeInValue(date1, date2, function(output) {
    //code that does something with output.
});

对输出执行某些操作的代码将按照您希望的方式运行 - 即在请求返回后立即运行。不同之处在于,当请求正在进行时,系统的其余部分也将继续工作。