Mat*_*ava 3 html javascript jquery promise
我想问一下javascript中的承诺是如何运作的.我很难理解由jQuery.animate和setTimeout组成的链的执行之间的区别.
如果我做这样的事情:
var promise = new Promise(function(resolve, reject) {
resolve(
$("#something").animate({
width: 100
}, 1000);
)
});
promise.then(function(data) {
$("#something").animate({
height: 100
}, 1000);
});
Run Code Online (Sandbox Code Playgroud)
然后第二个动画在第一个动画完成后开始(这是想要的行为).另一方面,当我用例如更改.then(替换.animate)时,setTimeout它会在动画启动后立即执行(它不会等待动画结束).
promise.then(function(data) {
setTimeout(function() {
console.log("timeout started");
}, 1000);
});
Run Code Online (Sandbox Code Playgroud)
所以我的问题是:为什么第一种情况正常,第二种情况不正常?我认为异步任务以相同的方式处理.我应该如何更改代码以正确链接任何函数(等待先前的函数执行).
首先,jQuery将通过它的内置动画队列为您在同一对象上序列化动画.你不需要使用任何承诺来做到这一点.
所以,如果你想让你的两个动画一个接一个,你可以简单地做到这一点而不使用任何承诺:
$("#something").animate({width: 100}, 1000).animate({height: 100}, 1000);
Run Code Online (Sandbox Code Playgroud)
然后,如果你想使用jQuery动画的promises,你必须获得动画的承诺,如下所示:
$("#something").animate({width: 100}, 1000).promise();
Run Code Online (Sandbox Code Playgroud)
然后你可以使用那个承诺.then().
如果你想使用jQuery promises来控制动画,你可以这样做:
$("#something").animate({width: 100}, 1000).promise().then(function() {
$("#something").animate({height: 100}, 1000);
});
Run Code Online (Sandbox Code Playgroud)
只是打电话:
$("#something").animate({width: 100}, 1000);
Run Code Online (Sandbox Code Playgroud)
在您的原始代码中返回一个jQuery对象,这不是一个promise本身可以使用的东西.
如果你真的想创建自己的promise对象并自己解决它(jQuery动画不需要的东西,当你已经有一个可以使用的承诺时不推荐),你可以这样做,你可以使用完成函数动画来解决你的承诺(使用你的编码风格):
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);
});
Run Code Online (Sandbox Code Playgroud)
所以,现在来解释你的代码中发生了什么.在您的第一个示例中,您的承诺逻辑根本不起作用(它几乎只是编码错误).因此,两个动画都会被立即调用,但是因为jQuery将它们排队为你顺序运行,这就是你看到的行为.排序与破坏的承诺逻辑无关.
然后,当您setTimeout()进行第二次操作时,jQuery不再为您排队,因为它本身不是jQuery动画,并且您的promise逻辑仍然被破坏,因此两个操作同时执行.
如果你真的想要链接超时,那么你可以创建一个包含超时和promise的包装器,它可以是可链接的:
function timer(t) {
return new Promise(function(resolve, reject) {
setTimeout(function() {
resolve();
}, t);
});
}
timer(1000).then(function() {
// do something here
return timer(1000);
}).then(function() {
// do something here
});
Run Code Online (Sandbox Code Playgroud)
工作演示:http://jsfiddle.net/jfriend00/85Pr6/(需要内置承诺的浏览器)
| 归档时间: |
|
| 查看次数: |
680 次 |
| 最近记录: |