首先,jQuery通过其内置的动画队列为您对同一对象序列化动画。您不需要使用任何承诺来完成此操作。
因此,如果您希望您的两个动画一个接一个地执行,您可以简单地这样做,无需使用任何承诺:
$("#something").animate({width: 100}, 1000).animate({height: 100}, 1000);
如果你想在jQuery动画中使用promises,你需要通过以下方式获取动画的promise:
$("#something").animate({width: 100}, 1000).promise();
然后,您可以使用该Promise与.then()
。
如果您想使用jQuery Promise来控制动画,则可以执行以下操作:
$("#something").animate({width: 100}, 1000).promise().then(function() {
$("#something").animate({height: 100}, 1000);
});
只需调用:
$("#something").animate({width: 100}, 1000);
在您的原始代码中,返回的是一个jQuery对象,这不是promise本身可以使用的东西。
如果您真的想创建自己的promise对象并自行解决它(在使用jQuery动画时不需要,并且当已经有一个可用的promise时不建议这样做),您可以像以下示例一样使用动画的完成函数来解决promise(使用您的编码风格):
var promise = new Promise(function(resolve, reject) {
$("#something").animate({width: 100}, 1000, resolve);
});
promise.then(function(data) {
console.log("timeout started");
setTimeout(function() {
console.log("timeout finished");
}, 1000);
});
所以,现在来解释一下你的代码中发生了什么。在你的第一个例子中,你的promise逻辑根本没有起作用(基本上是编码错误)。因此,两个动画都会立即被调用,但由于jQuery为您顺序排队运行它们,这就是您看到的行为。排序与您的破碎的promise逻辑无关。
然后,当您为第二个操作放入
setTimeout()
时,jQuery不再为您排队,因为它本身不是jQuery动画,并且您的promise逻辑仍然存在问题,因此两个操作同时执行。
如果您真的想要仅链接超时,则可以创建一个将超时与promise组合在一起的包装器,这可以是可链接的:
function timer(t) {
return new Promise(function(resolve, reject) {
setTimeout(function() {
resolve();
}, t);
});
}
timer(1000).then(function() {
return timer(1000);
}).then(function() {
});
工作演示:http://jsfiddle.net/jfriend00/85Pr6/(需要内置承诺的浏览器)
setTimeout()
并期望它们连续。 Promise 没有一些神奇的东西知道它们中的操作何时完成。 它们通过一系列回调工作,并且其中的操作必须解决Promise,并在返回时可以链接到另一个Promise操作。 - jfriend00