Tone.js 序列进度与状态监控完整指南

发布时间 - 2026-01-29 00:00:00    点击率:

本文详解如何在 tone.js 中准确获取序列(sequence)的播放状态和进度,包括 `state` 和 `progress` 属性的真实行为、常见误区及可靠事件监听方案,助你精准触发完成回调。

在 Tone.js 中,Tone.Sequence 的 state 和 progress 属性常被开发者误用——它们并非实时反映当前播放位置或生命周期状态的通用指标,而是有特定语义和使用前提。

✅ 正确理解 state 与 progress

  • seq.state 是一个字符串,返回 "started"、"stopped" 或 "paused",仅在显式调用 .start()、.stop()、.pause() 后同步更新。它不会因音频时钟推进而自动刷新,且不表示“是否正在渲染音符”——例如,在 start(0) 后立即读取,可能仍为 "stopped"(因异步调度尚未生效)。

  • seq.progress 仅在启用循环(loop: true)时有意义:它返回 [0, 1) 区间内的归一化值,表示当前循环内已执行步数占比(如 4 步序列执行到第 2 步时为 0.5)。若 loop: false(默认),该值恒为 0,无法用于判断单次播放进度或是否完成

因此,你示例中在回调内打印 seq.state 和 seq.progress 始终为 0,是完全符合设计预期的行为,并非 Bu

g。

✅ 推荐方案:使用事件监听替代轮询

要可靠地检测序列完成(尤其是单次播放),应监听 ended 事件,而非依赖 progress:

const synth = new Tone.FMSynth().toDestination();
const notesArray = [
  { note: "B2", duration: "16n" },
  { note: "B3", duration: "16n" },
  { note: "A2", duration: "16n" },
  { note: "G2", duration: "16n" },
  { note: "B4", duration: "16n" }
];

const seq = new Tone.Sequence(
  (time, note) => {
    synth.triggerAttackRelease(note.note, note.duration, time, 0.1);
  },
  notesArray,
  {
    subdivisions: 1, // 每个数组元素对应 1 步(默认即 1)
    loop: false      // 明确禁用循环
  }
).start(0);

// ✅ 正确:监听 ended 事件触发完成逻辑
seq.onended = () => {
  console.log("✅ Sequence completed!");
  // 在此处执行你的完成回调,如切换 UI、启动下一环节等
};

// ⚠️ 注意:Tone.js 14+ 中推荐使用 addEventListener 以兼容未来变更
// seq.addEventListener('ended', () => { ... });

✅ 进阶:手动追踪进度(需自定义)

若需精确知道当前执行到第几步(如用于 UI 进度条),可结合 index 参数与 subdivisions 手动计数:

let currentStep = 0;
const totalSteps = notesArray.length;

const seq = new Tone.Sequence(
  (time, note, index) => {
    currentStep = index; // 0-based index of current callback invocation
    synth.triggerAttackRelease(note.note, note.duration, time, 0.1);

    console.log(`Playing step ${index + 1}/${totalSteps} → ${note.note}`);
    if (index === totalSteps - 1) {
      console.log("➡️ Final note triggered — sequence will end shortly.");
    }
  },
  notesArray,
  { subdivisions: 1 }
).start(0);

seq.onended = () => {
  console.log(`? Full sequence finished. Total steps: ${totalSteps}`);
  currentStep = -1; // 重置
};

⚠️ 注意事项总结

  • ❌ 不要依赖 seq.progress 判断单次播放进度——它仅对循环序列有效;
  • ❌ 避免在音符回调中直接读取 seq.state 判定播放中状态——它滞后且不可靠;
  • ✅ 优先使用 onended 事件捕获完成时机;
  • ✅ 如需步进控制,利用回调函数的 index 参数 + subdivisions 配置;
  • ✅ 确保调用 Tone.start()(尤其在用户交互后)以解锁 Web Audio 上下文,否则序列可能静默失败。

通过以上方法,你将能稳健、精准地掌控 Tone.js 序列的生命周期与执行状态。


# js  # 回调函数  # 事件捕获  # red  # 字符串  # 循环 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: HTML5建模怎么导出为FBX格式_FBX格式兼容性及导出步骤【指南】  如何用狗爹虚拟主机快速搭建网站?  利用JavaScript实现拖拽改变元素大小  黑客入侵网站服务器的常见手法有哪些?  Laravel事件监听器怎么写_Laravel Event和Listener使用教程  网易LOFTER官网链接 老福特网页版登录地址  详解Nginx + Tomcat 反向代理 如何在高效的在一台服务器部署多个站点  laravel怎么用DB facade执行原生SQL查询_laravel DB facade原生SQL执行方法  如何快速搭建虚拟主机网站?新手必看指南  Laravel如何部署到服务器_线上部署Laravel项目的完整流程与步骤  Laravel如何使用.env文件管理环境变量?(最佳实践)  Laravel如何实现用户角色和权限系统_Laravel角色权限管理机制  Laravel怎么在Blade中安全地输出原始HTML内容  Win11搜索不到蓝牙耳机怎么办 Win11蓝牙驱动更新修复【详解】  Google浏览器为什么这么卡 Google浏览器提速优化设置步骤【方法】  Laravel安装步骤详细教程_Laravel环境搭建指南  Laravel数据库迁移怎么用_Laravel Migration管理数据库结构的正确姿势  网站制作大概要多少钱一个,做一个平台网站大概多少钱?  Laravel如何将应用部署到生产服务器_Laravel生产环境部署流程  Laravel如何获取当前用户信息_Laravel Auth门面获取用户ID  UC浏览器如何设置启动页 UC浏览器启动页设置方法  JS碰撞运动实现方法详解  小米17系列还有一款新机?主打6.9英寸大直屏和旗舰级影像  教你用AI润色文章,让你的文字表达更专业  深圳网站制作平台,深圳市做网站好的公司有哪些?  专业商城网站制作公司有哪些,pi商城官网是哪个?  Laravel如何获取当前登录用户信息_Laravel Auth门面使用与Session用户读取【技巧】  html如何与html链接_实现多个HTML页面互相链接【互相】  香港服务器租用费用高吗?如何避免常见误区?  Laravel全局作用域是什么_Laravel Eloquent Global Scopes应用指南  如何实现建站之星域名转发设置?  Laravel Seeder怎么填充数据_Laravel数据库填充器的使用方法与技巧  Laravel Eloquent访问器与修改器是什么_Laravel Accessors & Mutators数据处理技巧  移动端手机网站制作软件,掌上时代,移动端网站的谷歌SEO该如何做?  Laravel如何处理文件上传_Laravel Storage门面实现文件存储与管理  如何制作公司的网站链接,公司想做一个网站,一般需要花多少钱?  Laravel如何实现数据库事务?(DB Facade示例)  韩国代理服务器如何选?解析IP设置技巧与跨境访问优化指南  Laravel如何集成Inertia.js与Vue/React?(安装配置)  如何快速查询网址的建站时间与历史轨迹?  laravel怎么配置Redis作为缓存驱动_laravel Redis缓存配置教程  如何用花生壳三步快速搭建专属网站?  Laravel事件和监听器如何实现_Laravel Events & Listeners解耦应用的实战教程  Laravel怎么实现微信登录_Laravel Socialite第三方登录集成  Java Adapter 适配器模式(类适配器,对象适配器)优缺点对比  米侠浏览器网页背景异常怎么办 米侠显示修复  历史网站制作软件,华为如何找回被删除的网站?  Android中Textview和图片同行显示(文字超出用省略号,图片自动靠右边)  网站制作企业,网站的banner和导航栏是指什么?  Laravel任务队列怎么用_Laravel Queues异步处理任务提升应用性能