javascript-$ .getJSON函数期间设置的变量只能在函数内访问
这可能是一个范围更广的问题。 我正在尝试在$ .getJSON函数中设置一个JSON对象,但我需要能够在回调之外使用该对象。
var jsonIssues = {}; // declare json variable
$.getJSON("url", function(data) {
jsonIssues = data.Issues;
});
// jsonIssues not accessible here
在另一篇文章中也提出了类似的问题,共识是我需要对JSON对象做的任何事情都必须在回调函数中完成,而不能在其他任何地方访问。 真的没有办法继续在$ .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!!
将后续评论添加到我的回答中(我非常感谢)。 我这样做的目的是首先用一个Issues列表加载JSON对象,然后用户可以从中删除并保存。 但这是通过页面上的后续交互完成的,而且我无法预见用户将要对回调中的JSON对象执行的操作。 因此,需要在回调完成后使其可访问。 有人在这里看到我的逻辑缺陷吗? 严重的是,因为可能有些东西我没看到...
另外,我阅读了.ajax()jQuery文档,并说将async设置为false“将同步加载数据。在请求处于活动状态时阻止浏览器。最好在需要同步时通过其他方式阻止用户交互 ”。
有谁知道在这种情况下我应该如何阻止用户交互? 为什么这么担心? 再次感谢您的所有答复。
c
是异步的。 也就是说,在b
提取并解析数据并调用回调时,将执行调用后的代码。
因此,鉴于此:
a();
$.getJSON("url", function() {
b();
});
c();
c
、b
和c
的呼叫顺序可以是a b c
(在这种情况下是您想要的)或a c b
(实际发生的可能性更高)。
解决方案?
同步XHR请求
使请求同步而不是异步:
a();
$.ajax({
async: false,
url: "url",
success: function() {
b();
}
});
c();
重组代码
将呼叫移至b
之后将呼叫移至c
:
a();
$.getJSON("url", function() {
b();
c();
});
请记住,提供回调函数时,关键是将该回调的执行推迟到以后再立即继续执行下一步。 这是必需的,因为浏览器中的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线程也会阻塞浏览器中的所有其他内容,包括其他选项卡,甚至其他窗口。 那意味着没有滚动,没有导航,什么也没有。 出于所有意图和目的,似乎浏览器已崩溃。 您可以想象,以这种方式运行的页面对其用户来说是一个很大的麻烦。
也许这项工作对我有用.. :)
$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.
});
这是非常简单明了的方法,也是使异步代码更具必要性的可行方法。
“但是,这是通过页面上的后续交互完成的,我无法预见用户将要对回调中的JSON对象执行的操作。”
回调是您为用户与数据交互设置屏幕的机会。
您可以为用户创建或显示HTML,并设置更多回调。
大多数情况下,您的代码都不会运行。 对Ajax页面进行编程仅是考虑何时可能发生哪些事件。
有一个原因是“ Ajax”而不是“ Sjax”。 从异步更改为同步是一个痛苦的原因。 预计您将执行页面异步操作。
首先,事件驱动的编程可能令人沮丧。
我已经在JS中完成了计算密集型财务算法。 即便如此,这也是同一件事-您将其分解成小部分,事件就是超时。
JavaScript中的动画也是事件驱动的。 实际上,除非您的脚本反复放弃控制,否则浏览器甚至不会显示移动。
您只是遇到范围问题。
简短答案:
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中的作用域问题JavaScript封闭作用域问题