1

我有以下代码可能没有做我想要的。

function ajaxTempOff(f) {
    $.ajaxSetup({
        async: false
    });
    f();
    $.ajaxSetup({
        async: true
    });
}

function setAuthenticated() {
    ajaxTempOff(function() {
        $.when(
            $.getJSON(window.url_root + '/show/')
        ).done(function(data) {
            window.authenticated = data['is_user_authenticated'];
        });
    });

    return window.authenticated;
}

在这种情况下,JSON 调用是否同步执行?或者函数可以在$.getJSON完成之前返回吗?

4

1 回答 1

0

在任何情况下,$.when作为其参数提供的表达式将立即被计算。这就是 JS 的工作方式。

然而,这个案例很有趣。它在$.ajaxSetup 文档中被告知:

使用任何函数的所有后续 Ajax 调用都将使用新设置,除非被单独的调用覆盖,直到下一次调用 $.ajaxSetup()。

这就是这里发生的事情:

  • async设置为false全局优先,
  • ajaxTempOff然后逐步执行传递给的匿名函数
  • 在此函数中, call 使用当前设置的-$.when()评估$.getJSON表达式,此时请求是同步的asyncfalse
  • 在它解决后立即(在这种情况下确实是紧随其后 - 因为请求阻塞),它会触发.done()部分
  • 之后,.when().done()链下写的所有行都将被执行

底线是setAuthenticated在这种情况下将返回由 getJSON 调用设置的值。

我创建了一个类似的jsFiddle,为清楚起见修改了关键部分:

function setAuthenticated() {
    ajaxTempOff(function() {
        $.when(
            $.getJSON('/echo/json/')
        ).done(function(data) {
            console.log('Done');
            window.answer = 42;
        });
        console.log('Return');
    });
    return window.answer;
}
console.log( setAuthenticated() );

很容易验证,如果此函数作为传递给的回调调用,则将在 'Return'之前ajaxTempOff打印 'Done' ,最终记录将为 42 - 因为这就是答案。)

但是如果你按原样运行这个函数(或者只是注释掉 'async':false 设置,'Return' 将首先被打印,undefinedsetAuthenticated处理非阻塞请求的结果值) - 接下来,只有在请求之后实际会提交到服务器,最后Done会出现在日志中。

于 2013-09-07T00:27:18.940 回答