You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript:.then()传参规则与动画序列执行逻辑疑问

动画序列Promise执行顺序疑问解答

我在完成MDN《动画序列》教程的第二个练习时,写出了可行的代码,但对原理有疑问。代码如下:

const aliceTumbling = [
    { transform: 'rotate(0) scale(1)' },
    { transform: 'rotate(360deg) scale(0)' }
  ];
  
const aliceTiming = {
    duration: 2000,
    iterations: 1,
    fill: 'forwards'
}

const alice1 = document.querySelector("#alice1");
const alice2 = document.querySelector("#alice2");
const alice3 = document.querySelector("#alice3");


function sinc_animation() {
  const one = alice1.animate(aliceTumbling, aliceTiming)
  one.finished.then(() => alice2.animate(aliceTumbling, aliceTiming).finished)
  .then(() => alice3.animate(aliceTumbling, aliceTiming))
};

sinc_animation();

原本我希望第三个动画在第二个完成后执行,最初在第一个.then()中仅传入alice2.animate(aliceTumbling, aliceTiming),但第三个动画在第二个开始后立即启动,因为此时.then()的Promise被判定为已兑现。现在代码能正常按顺序执行,但有两个疑问:


1. .then()方法中可以传入什么参数?

  • .then()接受两个可选参数:第一个是Promise兑现(resolved)时触发的回调函数,第二个是Promise拒绝(rejected)时触发的回调函数(通常用.catch()单独处理错误会更清晰)。
  • 核心是第一个回调函数的返回值:
    • 如果返回的是一个Promise对象,后续的.then()会等待这个新Promise的状态变更(兑现或拒绝)后才会执行。
    • 如果返回的是非Promise值(比如普通数据、或者animate()返回的Animation对象),会被自动包装成一个已兑现的Promise,后续.then()会立刻执行。

2. 为什么返回alice2.animate().finished就能让动画按顺序执行?

  • 首先,element.animate()调用后会立刻启动动画,同时返回一个Animation对象;这个对象的finished属性是一个Promise,只有当动画完全结束时,这个Promise才会兑现。
  • 你最初的代码里,.then()回调直接返回alice2.animate(...)的结果(Animation对象,非Promise),所以.then()会马上把它包装成已兑现的Promise,导致第三个动画直接启动,完全不等第二个动画结束。
  • 而当你返回alice2.animate(...).finished时,回调函数返回的是一个Promise。这时Promise链会暂停,直到第二个动画结束(也就是这个finishedPromise兑现),才会执行下一个.then()里的第三个动画。同时,alice2.animate()已经触发了动画执行,所以第二个动画会正常运行,结束后才轮到第三个启动。

内容的提问来源于stack exchange,提问作者Darius

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 17:12:48