JavaScript - 从函数返回

时间:2014-11-28 03:22:58

标签: javascript ajax asynchronous stack stack-overflow

是否需要从JavaScript函数中明确返回?在其他语言中,当函数不返回时,我们往往会遇到 堆栈溢出 错误,但JavaScript似乎并非如此。

此外,由于是异步的,有时很难确定函数何时返回。它们甚至在AJAX调用或jQuery动画完成之前就会返回。

例如,函数进行AJAX调用,并且在返回AJAX结果之前不应返回。麻烦的是,AJAX函数在一个单独的异步线程中运行。我们如何从这样的功能中返回?

2 个答案:

答案 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事件。

请参阅:Does every Javascript function have to return a value?

答案 1 :(得分:1)

您似乎对JS的工作方式感到困惑:

  

一个函数进行AJAX调用,在返回AJAX结果之前不应返回。麻烦的是,AJAX函数在一个单独的异步线程中运行

本声明包含几个谬误:

  1. 一个函数进行AJAX调用,并且在返回AJAX结果之前不应返回
  2. AJAX函数在单独的异步线程中运行
  3. 这两个陈述都是完全不真实的,这就是原因:

    进行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;