jquery延迟函数(jquery延时)

JQuery 中的递延对象基于“Promise”的概念。为了理解所有关于Deferred对象的内容,让我们试着理解一个Promise是关于什么的

JQuery Deferred 对象是作为框架1.5版本的一部分引入的。JQuery 中的递延对象基于“承诺”的概念。为了理解所有关于延迟对象的内容,明智的做法是试图理解一个承诺的全部内容。

在我们的日常生活中,很多时候,我们不能依赖于某些行为的结果。然而,我们可能仍然需要根据预期的结果对未来做出决定。我们唯一能确定的就是我们会得到一个结果。这么说吧,我们把“结果”这个词包在一个漂亮的礼物包装里,称之为“承诺”

定义Promise

那么,什么是Promise?它不过是一个由方法返回的对象基于这个方法你可以决定未来的行动方针。让我们来做一个现实世界的类比:

你决定参加 X 公司的面试。

这是您打算执行的一个函数。面试是有结果的。你要么得到这份工作,要么没有。但无论面试结果如何,你都需要有一个计划。你现在就需要这个计划。面试后你不能为将来做打算。

例如,你可能需要预订一张旅行机票,或者如果面试通过,你可能需要预订一个聚会的地方。如果没有通过,你可能需要买一些书,然后向 Y 公司申请。

如果我们以编程的方式编写这个计划,我们最终会编写如下内容:

candidate.attendInterview().then(
successFunction(){
 //Book tickets.
 //Order a crate of beer for a party!
 },
failureFunction(){
 //Buy some more books to brush up
 //Apply to company Y
}
);

 

有趣的是,即使您不知道 attInterview 函数的确切结果,您也可以将一个方法链接到“假定的”结果,并指定在 attInterview 函数完成时应该调用的函数。

这是有可能的,因为 attInterview 函数将返回一个 ny 对象。这种模式的一个有趣的方面是承诺解决的概念。承诺解决据说发生在返回承诺的任务在现实中完成的时候。因此,当您从 attentInterview 函数返回一个  弧对象时,这个弧被称为未解析。

只有当手术结果出来时,也就是说,面谈的实际结果是在一段时间之后得到的时候,承诺对象才被称为得到解决。在解析时,根据解析的结果,将调用成功函数或失败函数。

承诺的概念很重要,因为有三个主要原因:

  1. 它帮助您将未来处理程序的逻辑与实际任务调用分离开来。
  2. 您可以添加任意数量的未来处理程序。
  3. 如果将处理程序添加到已经解决的誓言,则将立即激发适当的(成功或失败)函数。

在 Ajax 请求的上下文中使用承诺的好处变得更加明显。这是因为 Ajax 请求的结果在未来某个时间点可用,而且无法事先确定完成 Ajax 请求所需的时间量。

JQuery 中的延迟对象

JQuery 在库的1.5版本中引入了 Deferred 对象来处理这个场景。Deferred 对象实际上是一个  种伪接口的实现。它提供了所有的承诺功能,同时还允许您创建新的延迟对象,并将未来的处理程序附加到它们,并以编程方式解析它们。

让我们从 Ajax 请求的角度来看一下 jQueryDeferred 对象。

在1.5之前的 jQuery 版本中,为了将成功或失败处理程序附加到 Ajax 请求,在定义 Ajax 调用时需要声明一个成功回调函数。尽管这个方案比隐藏的 XMLHttpRequest 处理方便得多,但它有一个缺点: 将来要调用的函数(成功或失败)必须定义为 Ajax 函数的一部分。此外,不能将多个成功或失败处理程序附加到 Ajax 调用。

Here is how one would request using a version of jQuery prior to 1.5:

以下是在1.5之前使用 jQuery 版本的请求方式:

$.ajax({
  url: "test.html",
  success: function(){
    alert("ajax request succesful");
  },
  failure: function(){
    alert("ajax request failed");
  }
});

 

如上面的代码所示,您必须在发出 Ajax 请求时指定成功函数。此外,每个成功和失败只有一个可用的回调。

从 jQuery 1.5开始,延迟的引入彻底改变了游戏。这是一个渐进式的变化,因为它为 Ajax 功能增加了更多的有效性,为整个框架增加了更多的功能。

现在让我们调用与前面使用 jQuery > 1.5版本时看到的相同的 Ajax 调用:

var myRequest = $.ajax({  url: "test.html" })
 .done(function(data){
  alert('ajax request was successful');
  })
 .fail(function(data){
  alert('ajax request failed');
 });
  
 //After a few more lines of code
 myRequest.done(function(data){
  $('div.myclass').html('Ajax Response ' + data);
 });

 

正如您所看到的,这比之前调用 Ajax 请求的方法要好得多。完成和失败函数用于对 Ajax 调用返回的对象注册回调。Ajax 调用返回一个 Deferred 对象,这个对象实现了噪声接口。因为它是一个承诺,所以您可以将处理程序附加到它,以便当请求完成时,将来的处理程序将被调用。

我们还能够在稍后的时间点附加一个新的成功处理程序(done 函数的参数)。如果在到达该行之前,Ajax 请求还没有完成,那么函数将排队并在稍后调用。如果请求已经完成,那么在成功的情况下函数将立即激活。类似地,还可以向故障队列添加多个函数。

对延迟对象函数的进一步研究

这种方法使您在编写代码时具有很大的灵活性,并且使代码更加易读。Deferred 对象还有许多其他函数。其中一个非常有趣的函数是 when ()函数。这个函数非常有吸引力,因为它允许您将延迟对象分组在一起,然后在所有对象被解析或拒绝之后设置将来的处理程序。

这为创建依赖于多个源的输入但需要一起呈现的接口打开了大门。例如,某个 div 包含基于用户选择的信息,而用户选择导致触发两个不同的 Ajax 请求。如果您的数据的性质是,只有当来自两个请求的数据显示在一起时,信息才有意义,那么使用 when 函数将成为此类场景的完美候选者。

在下面的示例中,可以向两个不同的 URL 发出请求。只有在检索到两个 URL 中的数据之后,才会指定将来的函数作为要调用的参数:

$.when($.ajax("mypage1.html"), $.ajax("mypage2.html")).done(function(a1,  a2){
     $('div.page1details').html(a1[0]);
     $('div.page1details').html(a2[0]);
  });

 

请注意,when 函数中有两个函数调用。您可以拥有任意多的功能。唯一的条件是从函数调用返回的对象应该是一个  或一个延迟。如果这是个承诺,那好吧。如果它是一个 Deferred,那么将调用諾()函数,并从 Deferred 对象中检索  束对象。

创建一个父 Deferred 对象,该父对象将跟踪在 when 函数中定义的函数的所有 Deferred 对象。一旦解析了 when 函数中声明的所有函数,就会调用 done 函数。但是,如果在 when 函数中声明的任何函数失败,则调用失败回调,而不等待解析或拒绝其余函数。

您可以很容易地使用完成和失败函数来注册 Deferred 对象的未来回调。另一种可以做到这一点的方法是使用 then 函数。如果使用 when-then 函数组合,那么从语法上阅读代码就会容易得多,因为它看起来像是某种句子。让我们看一个使用 when-then 对的示例,这次我们还将看到如何注册多个回调:

$(function(){
     
    function fun1(data1, data2){
        console.log("fun1 : " + data1[0].query + " " +
                    data1[0].results.length);
        console.log("fun1 : " + data2[0].query + " " +
                    data2[0].results.length);
    }
     
    function fun2(data1, data2){
        console.log("fun1 : " + data1[0].query + " " +
                    data1[0].results.length);
        console.log("fun1 : " + data2[0].query + " " +
                    data2[0].results.length);    }
     
    function fun3(data){
        console.log("fun3 called upon faliure");
    }
     
    function fun4(data){
        console.log("fun4 called upon faliure");
    }   
     
    var successFunctions = [fun1, fun2];
    var failureFunctions = [fun3, fun4];
     
    $.when(
        $.ajax("http://search.twitter.com/search.json", {
            data: {
                q: 'jquery'
            },
            dataType: 'jsonp'
        })
    ,
        $.ajax("http://search.twitter.com/search.json", {
            data: {
                q: 'blogger'
            },
            dataType: 'jsonp'
        })
    ).then(successFunctions,failureFunctions);
     
});

 

在上面的示例中,我创建了四个函数。其中两个将在成功时被调用,两个将在失败时被调用。如您所见,我没有将单个函数作为参数传递给 then () ,而是为成功和失败回调传递了一个函数数组。这里需要注意的另一点是,由于 when ()函数中有两个 Ajax 请求,因此成功和失败方法可以接受两个参数。每个参数都将包含由相应的 Ajax 调用返回的 jqXHR 对象。因此,上面的示例演示了如何使用多个回调,以及如何使用从 JSON Ajax 请求获得的数据。

您可能还注意到,由于 Ajax 函数正在发出 JSONP 请求,因此我已经分别使用 data1[0]和 data2[0]在成功回调中引用了 JSON 对象。Data1和 data2对象实际上是形式为[ JSONObject,“ Success”,jqXHR ]的数组。在请求是普通 Ajax 请求而不是 JSONP 请求的情况下,您必须像往常一样使用 jqXHR 对象并检索 response seText。

以其他方式使用延迟对象

到目前为止,我们已经看到了一些示例,其中 Deferred 对象是由 Ajax 调用返回的对象。虽然经常与 Ajax 一起使用,但 Deferred 对象可以在其他地方使用。这方面的一个例子是在一组动画完成执行后运行将来的回调。您可以在 when ()函数中将动画组合在一起,然后,使用 Deferred 对象,您可以使用 then ()函数轻松地调用未来的回调。

这里的问题在于动画不返回 Deferred 对象。它们总是返回一个简单的 jQuery 对象。这就是延迟构造函数出现的地方。延迟构造函数可以用来创建一个新的 Deferred 对象,您可以将自定义代码封装在 Deferred 对象中,并返回包装器而不是 jQuery 对象。

让我们看一个例子。在下面的代码中,我们将发出一个 Ajax 请求并调整 div 的大小。这两个任务完成后,我们将在 div 中显示通过 Ajax 检索到的内容:

$(function(){
 
    function successFunction(data){
        console.log("successfunction");
        $('div.animateMe').html('Results : ' + data[0].results.length);
    }   
     
    function animateDiv(){
        //As per the documentation, the argument that is passed
        //to the constructor is the newly created deferred object
        var dfd = $.Deferred(function(dfd){
            $('div.animateMe').animate({height:'200px'},2000,dfd.resolve);
        });
         
        return dfd;
    }
     
    function failureFunction(){
        console.log("failureFunction");
    }
     
    $.when(
        $.ajax("http://search.twitter.com/search.json", {
            data: {
                q: 'jquery'
            },
            dataType: 'jsonp'
        }),animateDiv()
    ).then(successFunction,failureFunction);
});

 

您还可以查看 jsfiddle。

这个示例非常简单,因为它只是在解析 Deferred 对象之前等待 Ajax 请求和动画完成。这个示例的主要关注点是在 animateDiv 函数中创建一个 Deferred 对象。在这个函数中,我们首先创建一个新的 Deferred 对象。Deferred 对象的构造函数接受一个函数作为参数,在构造函数即将返回之前调用该参数。此函数将新创建的 Deferred 对象作为参数传递。在这个函数中,我们做了一个动画,在动画完成之后,我们指出框架通过将 Deferred 对象作为参数传递解析函数来解析 Deferred 对象。在下一行中,我们只是返回新创建的 Deferred 对象。

在上面的示例中,您可能已经注意到我们使用了一个“ decision”函数。此函数允许显式解析 Deferred 对象。虽然对于非 Ajax 请求,以编程方式解析 Deferred 对象的能力是可取的,但对于 Ajax 请求则不然。这是因为 Ajax 请求被认为只有在从服务器接收到响应时才能解析。因此 Ajax 请求的解析在 Ajax 函数内部进行,不应该直接提供给程序员。

对于非 Ajax 请求,如上例所示,程序员可以基于特定的需求解析 Deferred 对象。由于 Deferred 对象具有 decision 方法和许多其他附加方法,因此 Ajax 请求实际上返回一个  。这使您只能在结果对象上调用承诺接口的方法,从而防止在 Ajax 请求实际完成之前显式调用编程解析。

在创建非 Ajax Deferred 对象时,还有另一个方法-拒绝,它指示失败并调用失败队列的函数。毫无疑问,Deferred 对象有一个小而有用的 API。

总结一切

  1. JQuery 中的 Deferred 对象实现了  束规范。这意味着您可以在可以使用 Deferred 的任何地方使用承诺。
  2. 将来的处理程序可以添加到承诺对象中。
  3. 未来的处理程序在调用函数的解析(成功)或拒绝(失败)时被调用。可以将多个将来处理程序附加到任何延迟对象。
  4. 未来的处理程序可以接收参数,这些参数表示用于解析 Deferred 对象的信息。
  5. 通过使用 Deferred 构造函数,可以将非 Ajax 对象包装在 Deferred 对象中。
  6. jQuery When 方法可用于将许多 Deferred 对象组合在一起,并将未来的处理程序附加到这些对象上。
  7. 一旦解析了所有延迟对象,就会调用使用 when 函数的成功处理程序。
  8. 如果任何 Deferred 对象失败,则使用 when 函数的失败处理程序将被调用,而不管其余 Deferred 对象的状态如何。

 

我希望本文有助于帮助您理解承诺和延迟对象的概念。下面有几个链接对此有很好的解释。我建议你也看看它们,如果你还只是对事物有一个模糊的概念的话。

还有,可能有一两件事我误会了! 一定要指出来!

非常感谢!

jquery延迟函数(jquery延时)

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发表评论

登录后才能评论