如何在 JavaScript 游戏循环中实现动态递减的延迟时间

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

本文介绍如何使用 async/await 和 promise 封装 settimeout,构建一个每次执行间隔逐渐缩短的游戏循环,避免传统 while + settimeout 嵌套导致的“全部立即注册”问题。

在 JavaScript 中,直接在循环中多次调用 setTimeout 并不能实现“逐次等待后执行”的效果——因为 setTimeout 是异步且非阻塞的,所有定时器会在循环结束前就已注册完毕,导致它们几乎同时触发(仅因初始 delay 不同而略有错开),而非按预期顺序、逐轮等待执行。

要真正实现“每轮等待一个动态递减的时间后再进入下一轮”,必须让循环同步等待每个延迟完成。此时 async/await 是最清晰、可靠的方案。核心思路是:将 setTimeout 封装为返回 Promise 的函数,使 await timeout(delay) 暂停 async 函数执行,直到该延迟结束。

以下是可直接运行的完整示例:

// 将 setTimeout 封装为 Promise,便于 await
const timeout = (delay = 0) => new Promise(resolve => setTimeout(resolve, delay));

let game = null;

// 启动游戏循环(支持暂停/重启)
const start = () => {
  stop(); // 确保无残留实例
  game = { running: true };
  console.log('? 游戏启动');

  (async function loop() {
    let delay = 1000; // 初始延迟(毫秒)

    while (game.running && delay > 0) {
      await timeout(delay); // ✅ 真正等待 delay 毫秒
      console.log(`✅ 执行动作 — 当前延迟: ${delay}ms`);

      // 自定义游戏逻辑放在这里(如更新状态、渲染、触发事件等)
      // doGameUpdate();

      delay -= 100; // 每轮减少 100ms(可根据需求调整步长)
    }

    if (!game.running) {
      console.log('⏸️ 游戏已暂停');
    } else {
      console.log('? 循环结束(delay ≤ 0)');
    }
  })();
};

const stop = () => {
  if (game) {
    game.running = false;
  }
};

// 绑定按钮事件(HTML 中需有对应按钮)
document.getElementById('startbtn').onclick = start;
document.getElementById('stopbtn').onclick = stop;

配套 HTML(简洁可用):

立即学习“Java免费学习笔记(深入)”;


⚠️ 关键注意事项

  • ❌ 避免在普通 while 或 for 循环中直接调用 setTimeout——它不会阻塞循环,所有定时器会瞬间注册;
  • ✅ 必须使用 async/await + Promise 包装的延迟,才能实现“串行等待”;
  • ? 若需无限循环(如持续加速直到某条件),请将 while (delay > 0) 改为 while (game.running),并用外部状态控制生命周期;
  • ⏱ 建议设置最小延迟下限(如 delay = Math.max(50, delay - 100)),防止过快导致 UI 卡顿或逻辑失控。

通过这种方式,你不仅能精准控制每轮延迟,还能随时暂停、重置循环,为节奏渐强的游戏机制(如躲避加速、反应挑战等)提供坚实基础。


# javascript  # java  # html  # ai 


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


相关推荐: Laravel如何实现多对多模型关联?(Eloquent教程)  Internet Explorer官网直接进入 IE浏览器在线体验版网址  Laravel如何实现全文搜索_Laravel Scout集成Algolia或Meilisearch教程  免费网站制作appp,免费制作app哪个平台好?  香港服务器网站推广:SEO优化与外贸独立站搭建策略  如何在云虚拟主机上快速搭建个人网站?  详解一款开源免费的.NET文档操作组件DocX(.NET组件介绍之一)  Laravel Sail是什么_基于Docker的Laravel本地开发环境Sail入门  iOS UIView常见属性方法小结  DeepSeek是免费使用的吗 DeepSeek收费模式与Pro版本功能详解  如何快速搭建FTP站点实现文件共享?  使用spring连接及操作mongodb3.0实例  JavaScript Ajax实现异步通信  laravel服务容器和依赖注入怎么理解_laravel服务容器与依赖注入解析  昵图网官方站入口 昵图网素材图库官网入口  如何用wdcp快速搭建高效网站?  如何在万网自助建站平台快速创建网站?  html如何与html链接_实现多个HTML页面互相链接【互相】  JavaScript模板引擎Template.js使用详解  Laravel怎么配置.env环境变量_Laravel生产环境敏感数据保护与读取【方法】  Laravel Livewire是什么_使用Laravel Livewire构建动态前端界面  Linux系统命令中screen命令详解  浅析上传头像示例及其注意事项  详解Android图表 MPAndroidChart折线图  Laravel如何正确地在控制器和模型之间分配逻辑_Laravel代码职责分离与架构建议  手机怎么制作网站教程步骤,手机怎么做自己的网页链接?  Python结构化数据采集_字段抽取解析【教程】  如何在阿里云ECS服务器部署织梦CMS网站?  香港服务器建站指南:免备案优势与SEO优化技巧全解析  三星、SK海力士获美批准:可向中国出口芯片制造设备  Laravel如何构建RESTful API_Laravel标准化API接口开发指南  小视频制作网站有哪些,有什么看国内小视频的网站,求推荐?  如何自定义safari浏览器工具栏?个性化设置safari浏览器界面教程【技巧】  企业网站制作这些问题要关注  Laravel Artisan命令怎么自定义_创建自己的Laravel命令行工具完全指南  javascript基本数据类型及类型检测常用方法小结  Laravel如何发送系统通知_Laravel Notifications实现多渠道消息通知  如何快速生成橙子建站落地页链接?  在线制作视频网站免费,都有哪些好的动漫网站?  高配服务器限时抢购:企业级配置与回收服务一站式优惠方案  INTERNET浏览器怎样恢复关闭标签页_INTERNET浏览器标签恢复快捷键与方法【指南】  详解Android中Activity的四大启动模式实验简述  利用 Google AI 进行 YouTube 视频 SEO 描述优化  宙斯浏览器怎么屏蔽图片浏览 节省手机流量使用设置方法  如何生成腾讯云建站专用兑换码?  Windows10怎样连接蓝牙设备_Windows10蓝牙连接步骤【教程】  如何在云主机上快速搭建多站点网站?  Win11关机界面怎么改_Win11自定义关机画面设置【工具】  怎样使用JSON进行数据交换_它有什么限制  网站图片在线制作软件,怎么在图片上做链接?