是否需要从JavaScript函数中明确返回?在其他语言中,当函数不返回时,我们往往会遇到 堆栈溢出 错误,但JavaScript似乎并非如此。
此外,由于是异步的,有时很难确定函数何时返回。它们甚至在AJAX调用或jQuery动画完成之前就会返回。
例如,函数进行AJAX调用,并且在返回AJAX结果之前不应返回。麻烦的是,AJAX函数在一个单独的异步线程中运行。我们如何从这样的功能中返回?
答案 0 :(得分:1)
不要求从JavaScript函数明确返回。
The trouble is, the AJAX function runs in a separate asynchronous thread. How would we return from such a function?
所有JavaScript函数都将在其范围的末尾返回。如果未定义return语句,则函数将返回 undefined 。 AJAX调用将返回回调,并在完成后导致readystatechange
事件。
答案 1 :(得分:1)
您似乎对JS的工作方式感到困惑:
一个函数进行AJAX调用,在返回AJAX结果之前不应返回。麻烦的是,AJAX函数在一个单独的异步线程中运行
本声明包含几个谬误:
这两个陈述都是完全不真实的,这就是原因:
进行ajax调用的函数就是这样:它进行调用,然后发送请求。 AJAX代表Asynchronous JavaScript And XML,这是一个发出请求的函数,然后在发送请求后返回。请求发生了什么,以及一旦发回响应就处理它是不发出请求的函数的责任。考虑一下:
function sendInfo(info)
{
var loader = $('#loader');
$.ajax({
url: 'your/url',
data: info,
type: 'post',
success: function(response)
{//this will get called when there is a response
loader.hide();//access to outer scope!
}
});
loader.show();
}
在这种情况下,$.ajax
是执行请求的函数。如果那是阻塞,我们将无法显示加载器。但是,该函数在发送请求后返回,并且一旦有响应处理,将调用success
回调。该功能将负责加载器,即再次隐藏它。如果AJAX通话被阻止,我们就不会拥有像今天所有网站一样的响应式和动态网站(自动完成谷歌搜索,甚至是这个网站......)
AJAX函数在单独的线程中运行是不正确的。 AJAX是一种请求,您引用的函数要么是发出请求的函数,要么不在单独的线程中运行,要么是回调/句柄。这些也不在单独的线程中运行 JavaScript一直都是单线程的。 确实有一个事件循环。在每个事件中,JS检查是否有绑定处理该事件的侦听器。如果没有,那就是它的结尾,如果存在,这些处理程序将一次调用 一个 。在调用这些处理程序时,不能执行其他代码。
现在回答你的问题:我们如何从这些功能中回归?嗯,在某种程度上,你已经是:所有函数都返回一些东西。但我认为你想知道如何将这些函数的返回值赋给变量。简单的答案是:你不能。至少不是直接:
//not using jQuery:
var returnVal = xhr.send();
不会返回成功(onreadystatechange
)处理程序的值,只是因为onreadystatechange
事件将发生4次!你可以做的是使用闭包变量,模块模式,或者如果必须的话,使用全局变量
如果这些函数是在不同的线程中运行的,那么作用域和访问全局变量会给你带来很多并发问题,并且操作DOM也就行了。相反,你可以这样做:
var infoModule = (function()
{
var loader = $('#loader'),
module = {response: undefined};
module.sendInfo = function(info)
{
$.ajax({
url: 'your/url',
data: info,
type: 'post',
success: function(response)
{//this will get called when there is a response
loader.hide();//access to outer scope!
module.response = response;
}
});
loader.show();
};
return module;
}());
现在你可以这样做:
infoModule.sendInfo({data: 'foo'});
在请求完成后,您可以像这样得到呼叫的响应:
infoModule.response;