如何在 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进行数据交换_它有什么限制
网站图片在线制作软件,怎么在图片上做链接?
上一篇:linux怎么检查文件是否存在
上一篇:linux怎么检查文件是否存在

