这可能更像是一个范围问题。我正在尝试在$ .getJSON函数中设置JSON对象,但我需要能够在回调之外使用该对象。
var jsonIssues = {}; // declare json variable
$.getJSON("url", function(data) {
jsonIssues = data.Issues;
});
// jsonIssues not accessible here
在另一篇文章中提到了类似这样的问题,并且大家一致认为我需要在回调函数中完成我需要做的任何事情,并且无法在其他任何地方访问。我真的没办法在$ .getJSON回调之外继续访问/操作那个JSON对象吗?如何返回变量或设置全局?
我很感激任何帮助。这似乎不对......
更新
尝试将$ .ajax()异步设置设置为false,并运行相同的代码,没有运气。我试过的代码如下:
var jsonIssues = {}; // declare json variable
$.ajax({ async: false });
$.getJSON("url", function(data) {
jsonIssues = data.Issues;
});
// jsonIssues still not accessible here
另外,我有几个回应,全局变量应该可以正常工作。我应该澄清所有这些代码都在$(document).ready(function() {
之内。要设置全局变量,我应该在document.ready之前声明它吗?就这样:
var jsonIssues = {};
$(document).ready(function() {
var jsonIssues = {}; // declare json variable
$.getJSON("url", function(data) {
jsonIssues = data.Issues;
});
// now accessible?
}
我的印象是,document.ready中声明的变量应该在document.ready的任何部分中“全局”可访问和修改,包括$ .getJSON回调函数等子函数。我可能需要阅读javascript变量范围,但似乎并不容易实现我想要的。感谢所有回复。
更新#2: 根据以下答案的评论,我确实使用了$ .ajax 而不是 .getJSON,并取得了我想要的结果。代码如下:
var jsonIssues = {};
$.ajax({
url: "url",
async: false,
dataType: 'json',
success: function(data) {
jsonIssues = data.Issues;
}
});
// jsonIssues accessible here -- good!!
对我的答案采取后续评论(我非常感谢他们)。我这样做的目的是最初加载一个JSON对象,其中包含用户可以从中删除的问题列表,然后保存。但这是通过页面上的后续交互来完成的,我无法预见用户想要在回调中使用中的JSON对象。因此,一旦回调完成就需要使其可访问。有没有人在我的逻辑中看到一个缺陷?说真的,因为可能有些东西我没看到......
另外,我正在阅读.ajax()jQuery文档,它说将async设置为false“同步加载数据。在请求处于活动状态时阻止浏览器。最好通过其他方式阻止用户交互同步是必要的。“
有没有人知道在这种情况下我应该如何阻止用户互动?为什么这么关注?再次感谢所有回复。
答案 0 :(得分:34)
$.getJSON
是异步的。也就是说,执行调用后的代码会在$.getJSON
获取并解析数据并调用您的回调时执行。
所以,鉴于此:
a();
$.getJSON("url", function() {
b();
});
c();
a
,b
和c
的来电顺序可以是a b c
(你想要什么,在这种情况下)或a c b
(更有可能实际发生)。
解决方案?
使请求同步而不是异步:
a();
$.ajax({
async: false,
url: "url",
success: function() {
b();
}
});
c();
致电c
:
b
a();
$.getJSON("url", function() {
b();
c();
});
答案 1 :(得分:9)
请记住,当您提供回调函数时,其重点是将该回调的执行推迟到以后,并立即继续执行下一步。这是必要的,因为浏览器中的JavaScript的单线程执行模型。可以强制执行同步,但它会在整个操作期间挂起浏览器。在像$ .getJSON这样的情况下,浏览器停止响应的时间过长了。
换句话说,您正试图找到一种方法来使用这种程序范例:
var foo = {};
$.getJSON("url", function(data) {
foo = data.property;
});
// Use foo here.
当您需要重构代码时,它会更像这样:
$.getJSON("url", function(data) {
// Do something with data.property here.
});
如果你想让回调函数变得简单,那么“做某事”可能是对另一个函数的调用。重要的是你要等到$ .getJSON在执行代码之前完成。
您甚至可以使用自定义事件,以便在$ .getJSON之后放置的代码订阅了IssuesReceived事件,并在$ .getJSON回调中引发该事件:
$(document).ready(function() {
$(document).bind('IssuesReceived', IssuesReceived)
$.getJSON("url", function(data) {
$(document).trigger('IssuesReceived', data);
});
});
function IssuesReceived(evt, data) {
// Do something with data here.
}
<强>更新强>
或者,您可以全局存储数据,只需使用自定义事件来通知已接收数据并更新全局变量。
$(document).ready(function() {
$(document).bind('IssuesReceived', IssuesReceived)
$.getJSON("url", function(data) {
// I prefer the window.data syntax so that it's obvious
// that the variable is global.
window.data = data;
$(document).trigger('IssuesReceived');
});
});
function IssuesReceived(evt) {
// Do something with window.data here.
// (e.g. create the drag 'n drop interface)
}
// Wired up as the "drop" callback handler on
// your drag 'n drop UI.
function OnDrop(evt) {
// Modify window.data accordingly.
}
// Maybe wired up as the click handler for a
// "Save changes" button.
function SaveChanges() {
$.post("SaveUrl", window.data);
}
更新2:
回应:
有没有人知道在这种情况下我应该如何阻止用户互动?为什么这么关注?再次感谢所有回复。
您应该避免使用同步AJAX调用阻止浏览器的原因是被阻止的JavaScript线程也会阻止浏览器中的所有其他内容,包括其他选项卡甚至其他窗口。这意味着没有滚动,没有导航,没有任何东西。出于所有意图和目的,似乎浏览器已崩溃。您可以想象,以这种方式运行的页面对其用户来说是一个重要的麻烦。
答案 2 :(得分:5)
也许这项工作对我有用.. :)
$variable= new array();
$.getJSON("url", function(data){
asignVariable(data);
}
function asignVariable(data){
$variable = data;
}
console.log($variable);
希望它对你有所帮助.. :)
答案 3 :(得分:4)
你可以用承诺来解决这个问题:
var jsonPromise = $.getJSON("url")
jsonPromise.done(function(data) {
// success
// do stuff with data
});
jsonPromise.fail(function(reason) {
// it failed... handle it
});
// other stuff ....
jsonPromise.then(function(data) {
// do moar stuff with data
// will perhaps fire instantly, since the deferred may already be resolved.
});
这是非常直接的,并且使异步代码感觉更加必要的可行方法。
答案 4 :(得分:1)
“但这是通过页面上的后续交互来完成的,我无法预见用户将在回调中使用JSON对象做什么。”
回调是您为用户与数据交互设置屏幕的机会。
您可以为用户创建或显示HTML,并设置更多回调。
大多数情况下,您的代码都不会运行。对Ajax页面进行编程就是考虑在什么时候可能发生的事件。
有一个原因是它是“Ajax”而不是“Sjax”。将异步更改为同步是一件很痛苦的事。预计你会把页面异步。
事件驱动的编程起初可能令人沮丧。
我在JS中完成了计算密集型的财务算法。即使这样,它也是一样的 - 你把它分解成一小部分,事件就是超时。
JavaScript中的动画也是事件驱动的。事实上,除非您的脚本反复放弃控制,否则浏览器甚至不会显示运动。
答案 5 :(得分:-3)
您正在遇到范围问题。
简答:
window.jsonIssues = {}; // or tack on to some other accessible var
$.getJSON("url", function(data) {
window.jsonIssues = data.Issues;
});
// see results here
alert(window.jsonIssues);
答案很长:
Scoping issue in Javascript Javascript closure scoping issue