我的问题几乎与此问题相同: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()
,答案通常会告诉他们使用回调。
我想知道:
$.getJSON()
在此上下文中异步的优势是什么?var price = getSharePriceAtDate()
拨打电话,并在找到price
时等待我的代码编辑:我已经知道如何做getSharePriceAtDate(calculateChangeInValue);
这样的代码我写的代码可以真正做到能够在特定日期经常打印股价,我希望有更好的方法
答案 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/
答案 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.
});
对输出执行某些操作的代码将按照您希望的方式运行 - 即在请求返回后立即运行。不同之处在于,当请求正在进行时,系统的其余部分也将继续工作。