Return 来自异步调用示例的响应

Return response from asynchronous call example

我已经阅读这个 Whosebug post 好几遍 How do I return the response from an asynchronous call?。出于某种原因,我就是不明白。有人可以 post 此处问题中的示例作为实际的完整工作解决方案,而不是 post 的“2. 重组代码”部分中提供的分步指导,我发现这非常令人困惑。

function foo() {
    var result;

    $.ajax({
        url: '...',
        success: function(response) {
            result = response;
            // return response; // <- tried that one as well
        }
    });

    return result;
}

var result = foo(); // always ends up being `undefined`.

success 函数是一个回调,这意味着它可以随时调用。在这种情况下, ajax 调用之后被调用,return result; [=] 之前被调用25=] 调用,意味着 result 在返回之前没有被赋值,这就是为什么它总是未定义的原因。

我喜欢解决这个问题的一种方法是将我自己的回调传递给 foo 函数,然后在我收到数据时调用它,如下所示:

function foo(callback) {
    $.ajax({
        url: '...',
        success: function(response) {
            callback(response) // <-- call it here
        }
    });
}

foo(function(data){
    // use your data here
});

就目前情况而言,您几乎是立即从 foo 返回 result$.ajax() 被调用,函数立即移动到 return result,此时是 undefined;最后,当 ajax 调用完成时,您设置 result = response,但该功能早已完成(即 return result 再也不会发生)。

这就是异步调用通常使用回调或承诺的原因。这些是您在 异步调用完成后 工作的地方。在您的示例中,您可以使用承诺,例如:

function foo() {
    return $.ajax({
        url: '...'
    });
}

然后这样称呼它:

var result;
foo().done(function(response) {
    result = response;
});

或者,您可以通过回调来完成,例如:

function foo(callback) {
    return $.ajax({
        url: '...',
        success: callback
    });
}

并称其为:

var result;
foo(function(response) {
    result = response;
});

由于 ajax 请求是异步完成的,浏览器将继续执行代码,并且只会在请求完成(并成功)时返回您的回调(在 success: 下)。

这意味着如果您有依赖于请求响应的代码,则必须将其封装在内部您的回调中,以确保它不会预先执行。

$.ajax({
    url : '...',
    success : foo
});

function foo(response) {
    console.log('This executes AFTER the request finished');
    // do your thing with the response
}

console.log('This executes BEFORE the request finished');