很明显我不明白函数在Javascript中的作用域。这是最新的例子:
function riseData() {
var jsonResult;
$.ajax({
success: function(data, textStatus, jqXHR){
jsonResult = jqXHR.responseText;
alert("Inside: " + jsonResult);
},
error: function (jqXHR, textStatus, errorThrown) {
$('#errLog').append('<br>Status: ' + qXHR.statusText);
}
});
return jsonResult;
}
$(document).ready(function(){
var intervalID = setInterval('UTCclock()',100);
alert("Outside: " + riseData());
});
当我执行此操作时,“Inside”警报功能正常,但“Outside”警报显示“undefined”,即使roseData()显然只提前几行定义。代码中前面有一个$ .ajaxSetup,它定义了ajax调用的参数。 ajax调用成功返回“Inside”警报中的请求数据。
我只是没有丝毫知道如何将必要的数据(jqXHR.responseText)提供给脚本的其他部分。
任何人都可以指点我的“Javascript Scoping for Dummies”如何解决这个问题?
答案 0 :(得分:5)
你的例子范围很好。您的问题是您不了解JavaScript主要是异步的含义。
让我通过你的例子向你展示。
riseData
。riseData
声明变量jsonResult
。riseData
调用$.ajax
,它会安排完成一个AJAX请求,但响应会在稍后发生。$.ajax
通常是非阻止/异步的,riseData
会继续并返回jsonResult
。由于尚未完成jsonResult
,因为AJAX请求尚未完成,因此会返回默认值undefined
。alert("Outside: "+undefined);
。事件循环到几毫秒后,会发生这种情况:
jsonResult
已设置,但riseData
已返回。alert
之后,riseData
内部undefined
警报带有新数据。这个问题有两个解决方案。第一种解决方案很简单,但往往会导致更糟糕的用户体验。此解决方案是将async: false
选项添加到$.ajax
。这会使$.ajax
阻止并冻结浏览器。
第二种解决方案是对几乎所有东西都采用异步风格。这意味着让riseData
接受回调并在AJAX响应处理程序中调用它。这是使用此方法转换的代码:
function riseData(callback) {
$.ajax({
success: function(data, textStatus, jqXHR){
var jsonResult = jqXHR.responseText;
alert("Inside: " + jsonResult);
callback(jsonResult);
},
error: function (jqXHR, textStatus, errorThrown) {
$('#errLog').append('<br>Status: ' + qXHR.statusText);
}
});
}
$(document).ready(function(){
//var intervalID = setInterval('UTCclock()',100);
// Unrelated, but it's better to pass a
// function into setInterval than a string.
var intervalID = setInterval(UTCclock, 100);
riseData(function(jsonResult) {
alert("Outside: " + jsonResult);
});
});
答案 1 :(得分:0)
这只是部分范围问题。您的ajax调用是异步的,因此riseData()函数在执行ajax调用之前返回一个值。尝试在方法之外设置变量。
var jsonResult;
function riseData() {
$.ajax({
...
jsonResult不仅应该在riseData()中可用,而且还应该可用。但是,您仍然会遇到填充时的确切问题。
更多解释的链接: