Meg*_*att 45 javascript variables jquery scope callback
这可能更像是一个范围问题.我正在尝试在$ .getJSON函数中设置JSON对象,但我需要能够在回调之外使用该对象.
var jsonIssues = {}; // declare json variable
$.getJSON("url", function(data) {
jsonIssues = data.Issues;
});
// jsonIssues not accessible here
Run Code Online (Sandbox Code Playgroud)
在另一篇文章中提到了类似这样的问题,并且一致认为我需要在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
Run Code Online (Sandbox Code Playgroud)
另外,我有几个响应,全局变量应该可以正常工作.我应该澄清所有这些代码都在其中$(document).ready(function() {.要设置全局变量,我应该在document.ready之前声明它吗?因此:
var jsonIssues = {};
$(document).ready(function() {
var jsonIssues = {}; // declare json variable
$.getJSON("url", function(data) {
jsonIssues = data.Issues;
});
// now accessible?
}
Run Code Online (Sandbox Code Playgroud)
我的印象是,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!!
Run Code Online (Sandbox Code Playgroud)
对我的答案进行后续评论(我非常欣赏他们).我这样做的目的是最初加载一个JSON对象,其中包含用户可以从中删除的问题列表,然后保存.但是,这是通过在页面上后续交互做,我不能预见用户将要使用JSON对象做内回调.因此,一旦回调完成就需要使其可访问.有没有人在我的逻辑中看到一个缺陷?说真的,因为可能有些东西我没看到......
此外,我正在阅读.ajax()jQuery文档,它说将async设置为false"同步加载数据.在请求处于活动状态时阻止浏览器.最好在需要同步时通过其他方式阻止用户交互".
有没有人知道在这种情况下我应该如何阻止用户交互?为什么这么关注?再次感谢所有回复.
str*_*ger 35
$.getJSON是异步的.也就是说,在$.getJSON获取和解析数据并调用回调时执行调用后的代码.
所以,鉴于此:
a();
$.getJSON("url", function() {
b();
});
c();
Run Code Online (Sandbox Code Playgroud)
的调用的顺序a,b以及c可以是a b c(什么你想要的,在这种情况下)或者a c b(更可能实际发生).
解决方案?
使请求同步而不是异步:
a();
$.ajax({
async: false,
url: "url",
success: function() {
b();
}
});
c();
Run Code Online (Sandbox Code Playgroud)
将呼叫移至呼叫c后b:
a();
$.getJSON("url", function() {
b();
c();
});
Run Code Online (Sandbox Code Playgroud)
请记住,当您提供回调函数时,其重点是将该回调的执行推迟到稍后并立即继续执行下一步.这是必要的,因为浏览器中的JavaScript的单线程执行模型.可以强制执行同步,但它会在整个操作期间挂起浏览器.在像$ .getJSON这样的情况下,浏览器停止响应的时间过长了.
换句话说,您正试图找到一种方法来使用这种程序范例:
var foo = {};
$.getJSON("url", function(data) {
foo = data.property;
});
// Use foo here.
Run Code Online (Sandbox Code Playgroud)
当您需要重构代码以使其更像这样:
$.getJSON("url", function(data) {
// Do something with data.property here.
});
Run Code Online (Sandbox Code Playgroud)
如果你想保持回调函数的简单,"做某事"可能是对另一个函数的调用.重要的是你要等到$ .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.
}
Run Code Online (Sandbox Code Playgroud)
更新:
或者,您可以全局存储数据,只需使用自定义事件来通知已接收数据并更新全局变量.
$(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);
}
Run Code Online (Sandbox Code Playgroud)
更新2:
对此:
有没有人知道在这种情况下我应该如何阻止用户交互?为什么这么关注?再次感谢所有回复.
您应该避免使用同步AJAX调用阻止浏览器的原因是被阻止的JavaScript线程也会阻止浏览器中的所有其他内容,包括其他选项卡甚至其他窗口.这意味着没有滚动,没有导航,没有任何东西.出于所有意图和目的,似乎浏览器已崩溃.您可以想象,以这种方式运行的页面对其用户来说是一个重大的麻烦.
小智 5
也许这项工作,对我有用.. :)
$variable= new array();
$.getJSON("url", function(data){
asignVariable(data);
}
function asignVariable(data){
$variable = data;
}
console.log($variable);
Run Code Online (Sandbox Code Playgroud)
希望它能帮到你.. :)