$ .getJSON函数中设置的variables只能在函数内访问

这可能更多是一个范围问题。 我试图设置一个$ .getJSON函数内的JSON对象,但我需要能够在callback之外使用该对象。

var jsonIssues = {}; // declare json variable $.getJSON("url", function(data) { jsonIssues = data.Issues; }); // jsonIssues not accessible here 

在另一篇文章中也提到过类似的问题,我的共识是我需要做的JSON对象需要在callback函数中完成,并且不能在其他任何地方访问。 是否真的没有办法,我可以继续访问/操纵$ .getJSONcallback以外的JSON对象? 那么返回variables,或设置全局?

我会很感激任何帮助。 这似乎不正确…

更新:

尝试设置$ .ajax()asynchronous设置为false,并运行相同的代码,没有运气。 我试过的代码如下:

 var jsonIssues = {}; // declare json variable $.ajax({ async: false }); $.getJSON("url", function(data) { jsonIssues = data.Issues; }); // jsonIssues still not accessible here 

此外,我已经有一个全球variables应该很好的几个响应。 我应该澄清,所有这些代码是在$(document).ready(function() { 。要设置一个全局variables,我应该只是在document.ready之前声明它?因此:

 var jsonIssues = {}; $(document).ready(function() { var jsonIssues = {}; // declare json variable $.getJSON("url", function(data) { jsonIssues = data.Issues; }); // now accessible? } 

我的印象是document.ready中声明的variables应该在document.ready的任何部分是“全局”可访问和可修改的,包括像$ .getJSONcallback函数这样的子函数。 我可能需要阅读JavaScriptvariables范围,但似乎并不容易实现我要去的东西。 感谢所有的答复。

更新#2:每个评论给下面的答案,我用$ .ajax 而不是 .getJSON,并取得了我想要的结果。 代码如下:

 var jsonIssues = {}; $.ajax({ url: "url", async: false, dataType: 'json', success: function(data) { jsonIssues = data.Issues; } }); // jsonIssues accessible here -- good!! 

夫妇后续评论我的答案(我欣赏他们所有)。 我这样做的目的是首先加载一个JSON对象,然后用户可以从中删除问题列表,然后保存。 但是,这是通过页面上的后续交互完成的,我无法预见用户想要在callback中使用JSON对象。 因此,一旦callback完成,需要使其可访问。 有没有人在这里看到我的逻辑缺陷? 说真的,因为可能有些东西我没有看到

另外,我正在通过.ajax()jQuery文档阅读,它说asynchronous设置为false“同步加载数据,当请求处于活动状态时阻塞浏览器。最好是在需要同步时用其他方式阻止用户交互“。

有没有人有一个想法,我应该阻止用户交互,而这是怎么回事? 为什么这么担心? 再次感谢所有的回应。

$.getJSON是asynchronous的。 也就是说,调用之后的代码是在$.getJSON获取并分析数据并调用callback的时候执行的。

所以,鉴于此:

 a(); $.getJSON("url", function() { b(); }); c(); 

abc的调用顺序可以是abc (在这种情况下想要的)或者acb (更可能实际发生)。

解决scheme?

同步XHR请求

使请求同步而不是asynchronous:

 a(); $.ajax({ async: false, url: "url", success: function() { b(); } }); c(); 

重组代码

在呼叫c后,将呼叫转移到b

 a(); $.getJSON("url", function() { b(); c(); }); 

请记住,当你提供一个callback函数时,其重点是推迟callback的执行,直到后来立即继续执行下一个callback函数。 这是因为浏览器中JavaScript的单线程执行模型所必需的。 强制同步执行是可能的,但是它在整个操作期间挂起浏览器。 在类似$ .getJSON的情况下,浏览器停止响应的时间过长。

换句话说,你试图find一种方法来使用这个程序范式:

 var foo = {}; $.getJSON("url", function(data) { foo = data.property; }); // Use foo here. 

当你需要重构你的代码,使它更像这样stream动:

 $.getJSON("url", function(data) { // Do something with data.property here. }); 

如果你想保持callback函数的简单性,“做某事”可能是对另一个函数的调用。 重要的部分是,您要等到$ .getJSON完成才能执行代码。

您甚至可以使用自定义事件,以便在$ .getJSON之后放置的代码订阅了一个IssuesReceived事件,并在$ .getJSONcallback中引发该事件:

 $(document).ready(function() { $(document).bind('IssuesReceived', IssuesReceived) $.getJSON("url", function(data) { $(document).trigger('IssuesReceived', data); }); }); function IssuesReceived(evt, data) { // Do something with data here. } 

更新:

或者,您可以将数据全局存储,并使用自定义事件来通知已收到数据并更新全局variables。

 $(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. // (eg 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线程会阻塞浏览器中的其他所有内容 ,包括其他选项卡甚至其他窗口。 这意味着没有滚动,没有导航,没有任何东西。 对于所有意图和目的,似乎浏览器崩溃了。 正如你可以想象的那样,一个这样的页面对用户来说是一个很大的麻烦。

也许这项工作,对我工作.. 🙂

 $variable= new array(); $.getJSON("url", function(data){ asignVariable(data); } function asignVariable(data){ $variable = data; } console.log($variable); 

希望它可以帮助你.. 🙂

你可以用承诺来解决这个问题:

 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. }); 

这是非常简单的,一个可行的方法使asynchronous代码更加迫切。

“但是这是通过页面上后续的交互完成的,我不能预见用户想要在callback中使用JSON对象。

callback是您设置用户与数据交互的屏幕的机会。

您可以为用户创build或显示HTML,并设置更多的callback。

大多数时候,你的代码都不会运行。 编写一个Ajax页面是关于什么时候可能发生的事情。

有一个原因是“Ajax”,而不是“Sjax”。 从asynchronous转换到同步是一个痛苦的原因。 预计你会做页面asynchronous。

事件驱动编程起初可能令人沮丧。

我已经在JS中完成了计算密集型金融algorithm。 即使这样,也是一样的 – 你把它分解成小部分,事件就是超时。

JavaScript中的animation也是事件驱动的。 事实上,浏览器甚至不会显示动作,除非您的脚本反复放弃控制。

你只是遇到范围问题。

简短的回答:

 window.jsonIssues = {}; // or tack on to some other accessible var $.getJSON("url", function(data) { window.jsonIssues = data.Issues; }); // see results here alert(window.jsonIssues); 

长答案:

Javascript中的范围问题Javascriptclosures范围问题