繁体   English   中英

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

[英]How does one use $.deferred properly with non-observable functions?

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

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

如果我这样调用它,我如何确保function2没有与function1同时执行:

function1(); function2();

使用$.deferred 除了那些关于$.deferred之外的任何其他答案也欢迎!

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

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

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

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

下面的答案以及在.queue()和使用$.Deferred上阅读jQuery的API有助于澄清这一点。

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

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

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

但随着托默勒格指出,这是不必要的,除非你做一些非常棘手的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

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

function1();
function2();

除非它们包含异步调用,否则将逐个执行。 在这种情况下,总会有一个可以传递的回调(比如onSuccess for XmlHttpRequest)。 将第二个功能放在那里。

说实话, 即使它们包含异步位,它们也会严格执行。 只是在函数的其余部分时,异步位可能还没有完成。


编辑你的jsFiddle示例 ,修复( 见它 ):

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

就像我说的。 总会有一个你可以通过的回调。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM