使用async:false与回调函数和jqXHR.done()

时间:2015-08-21 06:15:21

标签: jquery html ajax synchronous

来自jQuery文档:

  

从jQuery 1.8开始,不推荐使用async:false和jqXHR($ .Deferred);您必须使用success / error / complete回调选项而不是jqXHR对象的相应方法,例如jqXHR.done()或不推荐使用的jqXHR.success()。

所以我从中理解的是:

//deprecated usage 
$.ajax({
    url: "test.html",
    async:false,
    context: document.body
}).done(function() {
    //code to be executed after response received .
});

//valid usage 
$.ajax({
    url: "file.php",
    type: "POST",
    async: false,
    success: function(data) {
        //means http request status successful
        //code to be executed after response received .
        // my code 
    }
});

来自jQuery docs:

  

默认情况下,所有请求都是异步发送的(默认情况下设置为true)。如果需要同步请求,请将此选项设置为false。 请注意,同步请求可能会暂时锁定浏览器,并在请求处于活动状态时禁用任何操作。

我的问题是:

  1. 据我所知,在这两种情况下,只有在收到回复后才会执行代码。两者都将浏览器锁定为async:false。那为什么一个是有效的而一个不是?我试图了解是什么使有效使用更好或我理解这一切都错了?

  2. 我知道同步请求不好(因为它们会阻止UI)并且不满意。但有时客户要求迫使你的手。对于注册表,我已经实施,我被要求使用谷歌reCAPTCHA。现在,客户希望在提交之前通知用户他们是否输入了错误的验证码。我通过在onsubmit JavaScript函数中使用同步ajax实现了这一点。怎么可以异步完成?没有某种阻塞,这可以以不同的方式实现吗?我正在寻找关于如何实现这一问题的替代想法,而不是这个问题的代码。

  3. 在谷歌搜索时,我确实找到了其他SO问题(链接),但找不到指定有效和弃用用法之间差异的答案。

3 个答案:

答案 0 :(得分:3)

修改

jQuery AJAX源代码的lines 619 - 622似乎为您提供了如何工作的答案:

completeDeferred.add( s.complete );
jqXHR.done( s.success );
jqXHR.fail( s.error );

所以在内部,$.ajax正在调用jqXHR.done并将状态成功函数作为回调传递,来自此处:

{
  success: yourSuccessFunction
}

line 776上,我们可以看到我们返回了一个jqXHR对象,这可以解释为什么(截至目前)我们能够链接.done()方法:< / p>

return jqXHR;

原始答案

  

据我了解,在这两种情况下,只有在收到回复后才会执行代码。两者都将浏览器锁定为async:false。那为什么一个是有效的而另一个不是。我试图了解是什么使有效使用更好或我理解这一切都错了?

两者都是&#34;有效&#34;,但.done已被弃用。 .done方法遵循promise模式,并且不推荐使用success回调。它有两种不同的执行模式,但两者都会有相同的结果。这只是使用不同API的举措。

例如,这里是promise模式(使用$ q库):

var deferred = $q.deferred();

// something async, then
deferred.resolve(data);

return deferred.promise;

success回调只是......一个回调:

function someFunction(cb) {
  // do something, then...

  return cb(data);
}

如果不推荐使用.done,这可能意味着在将来的jQuery版本中,$.ajax方法将不再返回promise对象,因此您无法调用.done方法。

  

我知道同步请求不好(因为它们会阻止UI)并且不满意。但有时客户要求迫使你的手。对于注册表,我已实施,我被要求使用谷歌recaptcha。现在,客户希望在提交之前通知用户他们是否输入了错误的验证码。我通过在onsubmit JavaScript函数中使用同步ajax实现了这一点。怎么可以异步完成?如果没有某种阻塞,这可以以不同的方式实现。我正在寻找关于如何实现这个问题的替代想法,而不是这个问题的代码。

我需要查看更多代码,但如果验证码内容异步发生,那么您需要先调用它,等待响应,然后执行表单提交:

checkCaptcha().then(function(result) {
  if(result === true) { // captcha passed the test
    // do your form submit
  } else {
    // possibly alert the user that the captcha didn't pass the test
  }
});

答案 1 :(得分:1)

我认为你应该避免 #include <iostream> #include <string> using namespace std; int main() { char ch; int countLetters = 0, countDigits = 0; cout << "Enter a line of text: "; cin.get(ch); while(ch != '\n'){ if(isalpha(ch)) countLetters++; else if(isdigit(ch)) countDigits++; ch = toupper(ch); cout << ch; //get next character cin.get(ch); } cout << endl; cout << "Letters = " << countLetters << " Digits = " << countDigits << endl; return 0; } ajax一般synchronous async: false已被弃用,.done(默认)async: true isn& #39; t,结果相同,但浏览器未被锁定

带有.done

async: false(如@ JoshBeam的答案中所示)在内部使用承诺(.done),因此您最终会使用它两次。

这应该是有效的,使用.done来同步代码执行:

$.when()

答案 2 :(得分:0)

从我收集的$.ajax async:false将来的版本中将不会传回延迟对象,这就是为什么.done()无法工作,因为它需要延迟对象。

对于您描述的情况,您不需要同步ajax调用。您要做的是阻止提交处理程序中的表单提交,然后在异步ajax调用成功处理程序中,您将检查验证码是否正确并从那里提交表单。这样你可以放入自定义加载动画和类似的东西