4

http://jsfiddle.net/jmztZ/

以上是我的问题的链接。假设我只有 1 个 div,其内容可能会通过 .html() 更改。我想使用 div 更改其内容并使用 animate() 或 show() 等显示自身。但是,当有 2 个操作 div 的函数时,浏览器的速度太快,似乎跳过了第一个 .html( ) 功能。

问题:我怎么能等到第一个函数(又名小提琴中的“go()”)完全执行(包括更改内容.html()和所有动画),然后再触发第二个函数(又名“went”)。

尝试:

注意:尽管我的这些尝试似乎分别在队列上执行动画,但 html() 函数永远无法等待。再看看小提琴。另外,我尝试了 Stackoverflow 上的几种方法,结果都一样。

我试过使用:

//Regular way, obviously didn't work
go(); went();

并使用延迟:

$.Deferred().done(go, went).resolve();

还有自调用函数:

var f = [go, went]; c = 0;
(function selfCall(){
    if (c >= f.length) return;
    f[c].call(); c++;
    selfCall();
})();

但它们似乎都不能正常工作。

所以最后,我将有一个数组,它可以使用 .push() 推送任意数量的函数来执行,这些函数都是关于操纵 div 的内容并对其进行动画处理。我想知道如何正确执行该数组中的所有功能,一个接一个,下一个必须等​​到当前一个完成。

4

4 回答 4

1

没有回调你不能做到这一点,但这里有一个工作。调用函数时,selfCall作为参数发送:

f[c].call(null, selfCall); c++; //null = this in function, but you don't use this.

然后,在 go 函数中,执行以下操作:

function go(callback) {
    $("#foo").html("GO");
    $("#foo").show("drop", 750).hide("explode", 500, callback);
}

小提琴:http: //jsfiddle.net/jmztZ/1/

于 2013-07-21T01:39:06.937 回答
1

试试这个。

function go() {
    $("#foo").html("GO");
    return $("#foo").show("drop", 750).hide("explode", 500).promise();
}
function going() {
    $("#foo").html("going");
    return $("#foo").show("drop", 750).hide("explode", 500).promise();
}
function gone() {
    $("#foo").html("gone");
    return $("#foo").show("drop", 750).hide("explode", 500).promise();
}
function went() {
    $("#foo").html("WENT");
    return $("#foo").show("drop", 750).hide("explode", 500).promise();
}
var arr = [go, going, gone, went],
    thisItem;

//randomize array
arr = arr.sort((function() { return 0.5 - Math.random();}));

function getNextArrayFn() {
    thisItem = arr.shift();
    thisItem().done(getNextArrayFn);
};
getNextArrayFn();

这是小提琴:http: //jsfiddle.net/jmztZ/31/

于 2013-07-21T03:48:59.697 回答
0

我想你可以试试一种叫做Monad的技术——但是Monad是什么?我无法正确解释。

所以,“请给我看代码!”

我们在一个数组中有一些异步函数,其中的pipequeue每个函数都pipequeue必须是一个deferred实例。该函数可以是异步的。他们将一一执行。

像这样:drop explode drop2 explode2有四个异步动画过程,每个都返回一个jQuery promise

完整的代码在 jsbin:http: //jsbin.com/ikovof/2/

var $el = $("#foo");
function drop(){
  var defer = Deferred()
    , promise = defer.promise()
  $el.html("GO");
  $el.show("drop",{
    complete:function(){
      defer.resolve();
    }
  },1000)
  return promise;
}

function explode(){
  var defer = Deferred()
    , promise = defer.promise()
  $el.hide("explode",{
    complete:function(){
      defer.resolve();
    }
  },1000)
  return promise;
}

function drop2(){
  var defer = Deferred()
    , promise = defer.promise()
  $el.html("WENT");
  $el.show("drop",{
    complete:function(){
      defer.resolve();
    }
  },1000)
  return promise;
}

function explode2(){
  var defer = Deferred()
    , promise = defer.promise()
  $el.hide("explode",{
    complete:function(){
      defer.resolve();
    }
  },1000)
  return promise;
}

var pipequeue = [drop,explode,drop2]

pipequeue.push(explode2);

pipe(unit(),pipequeue);

您可以pushpop pipequeue. 每个 fnpipequeue都没有耦合!

但如果你觉得pipe(unit(),pipequeue)有点...

您可以将调用包装unit()到一个函数中:

function pipePromise(pipequeue){
  pipe(unit(),pipequeue);
}
// then your call can be quite neat now  
pipePromise(pipequeue);
于 2013-07-21T06:25:40.237 回答
0

我喜欢Smee 先生的回答,但还有另一种选择。将 html 在回调中写入.hide(0, callback)

$("#foo").hide(0, function(){ $(this).html("GO"); });

http://jsfiddle.net/jmztZ/34/

您甚至可以按顺序调用它们:

http://jsfiddle.net/jmztZ/35/

于 2013-07-21T07:46:20.517 回答