Promise链式调用控制anime.js动画顺序的问题及优化咨询
如何让anime.js动画按顺序执行(优化Promise链式调用)
问题原因分析
你原来的代码里,两个then的回调会按顺序进入微任务队列执行,但move函数中的anime动画是异步操作,且move没有返回Promise等待动画完成。第一个then调用move(100)后,回调函数立刻执行完毕,下一个then随即触发move(-100),导致两个动画同时运行,无法实现顺序执行的效果。
最优解决方案
让move函数返回一个Promise,绑定动画的完成事件来resolve这个Promise,这样Promise链式调用会自动等待上一个动画完成后再执行下一个。
方案1:利用anime.js的finished属性(推荐)
anime.js的动画实例自带finished属性,这是一个会在动画完成时自动resolve的Promise:
const promise = new Promise((resolve) => { resolve() }) function move(y) { // 返回动画的finished Promise return anime({ targets: '.test', translateY: y }).finished; } promise .then(() => move(100)) .then(() => move(-100))
方案2:手动封装Promise(兼容旧版anime.js)
如果使用的anime.js版本没有finished属性,可以通过complete回调手动创建Promise:
function move(y) { return new Promise((resolve) => { anime({ targets: '.test', translateY: y, complete: resolve // 动画完成时调用resolve }); }); }
关于MDN文档内容的说明
你引用的MDN描述是正确的,但和你遇到的问题无关。它指的是then的回调不会在当前事件循环的同步代码执行完成前被调用——比如同步代码中调用promise.then(...),回调不会立刻同步执行,而是进入微任务队列等待当前同步代码跑完后再执行。而你的问题是then回调内部的异步动画没有被等待,回调本身执行完毕后就触发了下一个then,和事件循环的执行时机无关。
对比你的setTimeout方案
你用setTimeout硬等1秒的方式不够可靠:如果动画时长不是恰好1秒,要么会提前执行下一个动画(导致重叠),要么会浪费不必要的等待时间。绑定动画自身的完成事件才是最精准的方式。
内容的提问来源于stack exchange,提问作者user19967625
相关产品推荐
相关产品推荐

