5

例如,假设我有两个函数,其中包含随机代码,并且基于用户的系统(慢速、中速或快速),无法判断这两个函数需要多长时间才能完成,所以setTimeout使用function2 完成后才尝试射击时不实用function1

无论时间要求如何,并且考虑到这两个函数都是 100% 非 jQuery 函数,其中没有 jQuery 代码,因此 jQuery 完全无法观察到,你如何才能使用jQuery.deferred它来function2触发?最多,这些函数可能包括没有时间关联的 jQuery 方法,并且在旧计算机上运行速度较慢。 function1.css()

我如何确保它不会像我这样称呼它们function2的同时执行:function1

function1(); function2();

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

3 月 20 日添加: 如果 function1() 是一个 lambda 函数,根据用户输入,该函数可能有也可能没有异步调用,并且无法判断该函数将执行多少操作?这将是一个函数,您不知道接下来会发生什么,但无论如何,您仍然希望 function2 仅在 lambda 函数 (function1) 的所有内容完成执行,无论如何需要很长时间,但只要异步方面完成即可。如何做到这一点?

3 月 22 日添加: 所以我想,做我所要求的唯一方法是将匿名函数作为回调传递给异步函数,这些函数在完成后执行回调,或者创建事件侦听器,当事件最终被触发。

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

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

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

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

4

2 回答 2

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
于 2011-03-19T09:59:57.660 回答
5

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

function1();
function2();

除非它们包含异步调用,否则将一个接一个地执行。在这种情况下,总会有一个可以传递的回调(例如onSuccessXmlHttpRequest)。将第二个函数放在那里。

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


编辑您的 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();
    } 
  );
}

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

于 2011-03-19T09:12:32.670 回答