使用JavaScript将函数返回值赋值给某个变量

49
我有一个JS函数,在执行一些业务逻辑后,应该将一些结果返回给另一个变量。下面是示例代码。
var response="";
function doSomething() {  
    $.ajax({
        url:'action.php',
        type: "POST",
        data: dataString,
        success: function (txtBack) { 
            if(txtBack==1) {
                status=1;
            }
    });
    return status;     
}

我想要使用类似于以下的方式:

response=doSomething();
我想将返回值"status"分配给"var response",但结果是'undefined'。

你的标题已经使用了正确的术语:“返回值”。但是你的函数中没有使用 return 语句 ;) - Felix Kling
通常情况下,如果变量的值是假值(比如空字符串),你不需要为新变量初始化一个值。你只需要写:var response; 这种情况下response的值将会被设置为undefined(也是假值)。然后,在以后当你想要检查这个值是否被设置时,你只需要检查它是否是假值即可。 - Šime Vidas
@Felix:我在函数内部有一个ajax调用,它返回的是"undefined"。你有什么想法吗?谢谢 - Ra.
2
在SO上搜索此问题。这是正常的。您无法从Ajax调用中返回值,因为它是异步执行的,即return语句在Ajax调用完成之前执行。您可以使用回调函数来解决这个问题... - Felix Kling
@Felix:嗨,我在代码中做了一点小改动,在成功条件后,我只是加入了“async:false”……现在代码按预期正常工作 :) - Ra.
@Ra:但要记住async: false是不好的。根据Ajax调用需要多长时间,它会冻结浏览器。而且,我认为你失去了Ajax调用最重要的特性。 - Felix Kling
5个回答

84

或者只需...

var response = (function() {
    var a;
    // calculate a
    return a;
})();  

在这种情况下,响应变量接收函数的返回值。该函数立即执行。

如果您想要将一个需要计算的值填充到变量中,可以使用此构造。请注意,所有的计算都发生在匿名函数内部,因此您不会污染全局命名空间。


5
对于好奇的人来说,这被称为“立即调用函数表达式”(IIFE)。它非常棒。 - Scribblemacher
6
请注意,函数本身在括号内(在单词“function”之前有一个开括号),并且末尾有额外的()。(一开始看不太明显) - J0ANMM
我该如何使用这个语法传递参数? - Leonard Niehaus
@LeonardNiehaus (function(w) { /*…*/ })(window) (function(w){ // })(window) - Šime Vidas

21

AJAX请求是异步的。您的doSomething函数正在执行,AJAX请求正在异步进行,因此doSomething的其余部分被执行,当它返回时,status的值是未定义的。

实际上,您的代码的工作方式如下:

function doSomething(someargums) {
     return status;
}

var response = doSomething();

然后过了一段时间,您的AJAX请求正在完成;但为时已晚。

您需要修改代码,在AJAX请求的“success”回调中填充“response”变量。 您必须延迟使用响应,直到AJAX调用完成。

在以前可能有的地方:

var response = doSomething();

alert(response);
你应该这样做:
function doSomething() {  
    $.ajax({
           url:'action.php',
           type: "POST",
           data: dataString,
           success: function (txtBack) { 
            alert(txtBack);
           })
    }); 
};

9
你可以直接从函数中返回一个值:
var response = 0;

function doSomething() {
    // some code
    return 10;
}
response = doSomething();

它正在工作...但我在其中有一个ajax调用,在那个时候结果是“未定义”。有什么想法吗?请查看修改后的示例代码。 - Ra.

2
结果是undefined,因为$.ajax运行异步操作。这意味着return status$.ajax请求完成之前就被执行了。
您可以使用Promise,以获得类似同步的语法。
function doSomething() { 
    return new Promise((resolve, reject) => {
        $.ajax({
            url:'action.php',
            type: "POST",
            data: dataString,
            success: function (txtBack) { 
                if(txtBack==1) {
                    resolve(1);
                } else {
                    resolve(0);
                }
            },
            error: function (jqXHR, textStatus, errorThrown) {
                reject(textStatus);
            }
        });
    });
}

你可以这样调用Promise:

最初的回答

doSomething.then(function (result) {
    console.log(result);
}).catch(function (error) {
    console.error(error);
});

or this

(async () => {
    try {
        let result = await doSomething();
        console.log(result);
    } catch (error) {
        console.error(error);
    }
})();

2

在您的上下文中检索正确值的唯一方法是同步运行$.ajax()函数(这实际上与AJAX的主要思想相矛盾)。有一个特殊的配置属性async,您应该将其设置为false。在这种情况下,实际包含$.ajax()函数调用的主范围被暂停,直到同步函数完成,因此return仅在$.ajax()之后调用。

function doSomething() {
    var status = 0;
    $.ajax({
        url: 'action.php',
        type: 'POST',
        data: dataString,
        async: false,
        success: function (txtBack) {
            if (txtBack == 1)
                status = 1;
        }
    });

    return status;
}

var response = doSomething();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接