$ .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();
a
, b
和c
的调用顺序可以是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范围问题