如何在不可观察的函数中正确使用$ .deferred?

时间:2011-03-19 08:59:42

标签: javascript jquery jquery-deferred

比方说,我有两个函数,里面有随机代码,而且基于用户的系统(慢,中,或快),没有办法告诉这两个函数需要多长时间才能完成,所以在 setTimeout完成后尝试触发function2时,使用function1是不实际的。

无论时间要求是多少,并且考虑到两个函数都是100%,您如何使用jQuery.deferred仅在 function2之后function1触发非jQuery函数,里面没有jQuery代码,因此jQuery完全无法观察到?最多的功能可能包括.css()之类的jQuery方法,这些方法没有时间关联,并且可以在旧计算机上运行得更慢。

如果我这样打电话给function2,我如何确保function1没有与function1(); function2(); 同时执行:

$.deferred

使用$.deferred?除.queue()以外的任何其他答案也欢迎!

3月20日增加 如果function1()是一个lambda函数,如果根据用户输入,该函数可能有也可能没有异步调用,并且无法判断该函数将执行多少操作,该怎么办?它是一个函数,你不知道接下来会发生什么,但无论如何,你仍然希望function2只能在执行lambda函数(f​​unction1)后的所有内容时执行无论需要多长时间,只要异步方面完成,它就完成了。如何实现这一目标?

3月22日新增 所以我想我要问的唯一方法就是将匿名函数作为回调传递给异步函数,这些函数在完成后执行回调,或者创建事件监听器,在事件最终触发时执行你想要的操作

实际上没有任何方法可以在两个单独的行上执行异步调用并按顺序触发它们,而无需在包含所述函数的框架内手动构造机制(事件处理程序)来处理其操作的实际执行。

这些类型机制的一个很好的例子是jQuery的$.Defferred方法和.queue()对象。

以下答案以及在$.Deferred$.Deferred上阅读jQuery的API有助于澄清这一点。

Tgr在下面给出了一个很好的例子,说明如何使用jQuery的{{1}}对象创建自定义可链接函数,而自定义函数本身并不一定要在其中包含任何jQuery代码,这正是我所期待的对

2 个答案:

答案 0 :(得分:6)

function first(deferred) {
    // do stuff
    deferred.resolve();
}
function second() {
    // do stuff
}

$.Deferred(first).then(second);

但正如Tomalak指出的那样,这是不必要的,除非你在first做一些非常棘手的事情(比如利用网络工作者)。

<强>更新

基本思想是,无论何时执行非直接的操作,都会创建一个Deferred对象,并返回该对象。 (jQuery的AJAX调用已经这样做了。)然后你可以使用Deferred.then来延迟后续操作。

function first() {
    var deferred = $.Deferred();
    var callback = function() {
        deferred.resolve();
    }
    // do immediate stuff
    someAsyncOperation(callback);
    return deferred.promise(); // turns the Deferred into a Promise, which
                               // means that resolve() will not be accessible
}

function second() {
    // do stuff
}

first().then(second); // or: $.when(first).then(second)

如果second也是异步操作,您可以使用$.when的合并功能:

function second() {
    var anotherDeferred = $.Deferred();
    // do stuff with anotherDeferred
    return anotherDeferred.promise();
}

$.when(first(), second()).then(third); // third will run at the moment when 
                                   // both first and second are done

答案 1 :(得分:5)

JavaScript本身异步。它是单线程的,同步的。

function1();
function2();
除非包含异步调用,否则

将逐个执行。在这种情况下,总会有一个你可以传递的回调(比如onSuccess用于XmlHttpRequest)。将第二个功能放在那里。

说实话,他们严格执行一个接一个,即使它们包含异步位。只是当函数的其余部分为。时,异步位可能还没有完成。


编辑Your jsFiddle example,已修复(see it):

function foo() {
  $('#foo')
  .html('<span>foo1</span>')
  .animate(
    {              /* properties */
      left: '100px' 
    },      
    360,           /* duration */
    'swing',       /* easing */
    function () {  /* "complete" callback */
      $('#foo').append('<span>foo2</span>');
      bar();
    } 
  );
}

正如我所说。总会有一个你可以通过的回调。