JS异步变同步
因为Canvas动图绘制需要不定时间消耗,而又不能使用SetTimeout的递归操作,所以不得不将SetTimeout的异步改为同步了。
学习:here

function delate(x) { return new Promise(resolve => { setTimeout(() => { console.log(111); resolve(x); //必须有这一条指令,全靠他 同步了,且将实参原封不动 返回[可无] }, 2000); }); } (async function f1() { for(let j=0;j<10;j++){ var x = await delate(222);// 先 同步调用函数,输出 111 , console.log(x); //等待上一条 同步定时函数 执行结束后,再执行这一条 输出 222 } })()
另外,因为个人使用的操作更为复杂,所以需要进一步学习。
1.如果一个function包含async修饰的子function,而且自身没有使用async+await,那么其子function的执行将会是异步的。
2.async+await修饰的函数,可以递归调用其本身,符合正常逻辑运行。
3.在async表达式修饰的function中,没有await修饰的任意包含SetTimeout异步执行的部分,都会是异步执行。
总结一下,如果只是在一个function中要求其内部异步的SetTimeout同步执行,模板如下:
async function exam() { console.log("步骤1"); // 等待500ms await new Promise(solve => { setTimeout(() => { console.log("步骤2"); solve(); }, 500); }); console.log("步骤3"); }
另外,因为常用的图片资源的onload也是异步,所以写一份学习到的同步onload方法:

var num=0; for (let i=0; i<imgs.length; ++i) { console.log(imgs[i].src); imgs[i].onload=function (i) { console.log("i=="+i+" , 加载图片成功!"); num++; if (num==imgs.length) { console.log("这里执行全部加载完后的操作"); } }(i); }
另外,可能有需要是一个async对应多个await的情况,要使其符合预期运行逻辑顺序,必须要知道其await的执行顺序,学习参考:here
Promise绑定使用后,即顺序执行。
要注意的是,SetTimeout与SetInterval还是有很大区别的,SetInterval只管间隔时间循环执行,不能与async+await套用,
应对的解决办法
1.将SetInterval进行赋值,在时停的地方使用clearInterval(),待时停结束后再赋值SetInterval即可。
但是缺点是应用场景为每一次时停都得从头开始。
2.假性时停,使用帧的计数变量,每一次SetInterval函数体运行一次就+1,那么根据需要的时停时间固定给计数变量进行特判,当变量符合预期范围,才真正运行函数体内容,以实现时停的效果。
-----------------------------------下面这段没用,但是是一个需要解决的问题--------------------------------------------------------
另外,注意到因为这种onload加载方式通常为批量使用,而又存在多个imgs(变量名不同)的情况,所以将其封装成了通用函数:

function Onload_index(x) { for (let i=0; i<x.length; ++i) { x[i].onload=function (x, i) { console.log(x[i].src); console.log("加载完背景图片"+i+"!!!!!!!!!!!!!!!!!!"); }(x, i); } }
还有一点,使用这种通用函数的常识,js的形参和实参,学习:here
copy内容:
形参和实参是存在一种引用关系的,就好比变量中的引用关系。我们都知道,变量中的引用关系跟它们的值有关。
当值为原始类型时(string,number,boolean,int等等),var a=b是各自引用不同的内存地址的,修改不会影响到彼此;
当值是对象,数组等非原始类型时,它们引用的是同一个内存地址,修改则会相互影响。
所以当 函数中的形参是 原始类型,就不会影响到实参的值,因为引用的是值
当函数中的形参是 对象类型,引用的是地址,会影响实参。
-----------------------------------------------------------------------------------------------------------------------------------
使用经验:
使用canvas的drawImage绘制的图片,如果分有多次绘制,那么后续的绘制都是不需要onload处理的,比如有通过onclick事件绑定的绘制,那么该图片就不需要再进行onload处理。
也就是说,只需要onload处理首页显示所涉及到的Image即可。其他,直接draw。
【Over】
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
· 零经验选手,Compose 一天开发一款小游戏!