赏析大厂程序员代码
孙泽辉 Lv5

threejs中很多回调套回调,或是需要全局变量共享某个实例,往往容易造成代码写的一团乱麻,或是为了防止变成一团乱麻而写重复代码,这之间如何取舍,需要长久的经验积累。

之前由于写成一团乱麻,重构了一下,新版不能说有多好,反而导致模块间共享一些上下文变得复杂。

只能说在自己技术没有突破性提升的时候,重构等于啥也没干。

迫于自己水平低下,翻看被Vite打包的大厂员工代码,还能看,至少不是混淆。

模型加载

model-viewerscene上的属性,可以看做是总体的init

这里除了设置了renderer以外,还添加了模型加载完成的事件监听。对的,模型加载后就在这里执行一次回调,继续看是哪里触发了模型加载结束事件——

image

这里是模型元素上的属性,其属性src对应模型路径,dracoDecoderPath对应解压模型脚本路径。

这里的init只是生成了loader,加载模型的操作是在update方法,在这里加载模型相较于在init,相同的是都会在第一次挂载执行,唯一不同的是updatesetAttribute()时会再次执行。如果需要切换加载模型的时候,便可以将初始化代码区分开。

注意看this.ready这个属性对Promise的使用,这里没截图声明,目测应该是new了一个永远不会resolvePromise,而init后将其状态改为resolve,此时下面updatethis.ready.then便执行。巧妙地利用Promise实现事件监听(或是类似等待某种状态)

gltfLoader的函数签名大概是这样:

load(onSuccess, onProgress, onFail)

看大厂员工写的是三个回调都用事件传出去了,毕竟这里是抽象出来的代码,不要做具体逻辑。

model-loaded消息一经发出后,修改材质、添加贴图、动画处理事件处理函数都跑了起来,他们都是独立在其他地方,使用着他们的上下文。

同样的model-progress、model-error也有专门的处理器在等着。

image

其他的我还没来得及看,现在总结一下。

看完之后才发现自己水平差到极点,拿外面上下文只会传参数引用、回调函数,殊不知参数一多搞得人头晕眼花;暴露内部上下文也只会传回调函数,或是少有的几个变量就做引用返回值了。

代码写的千疮百孔,逻辑抽离效益甚微;实现操作只会封装成函数,从而依赖多个模块导致模块间聚合严重,可定制化极低。initupdate不分,重复构建相同对象;上下文暴露困难,经常依赖全局变量。

我自己写的代码就不贴了,反正就是加载gltf模型,各种操作一锅炖

最近在想,或许rxjs的魅力不仅仅在于函数式,更因为是将所有effect都化为事件去处理,模块间通信更清晰,不过怎么没见有rxjs配合threejs的?哈哈哈

 Comments
Comment plugin failed to load
Loading comment plugin
Powered by Hexo & Theme Keep
Total words 87.1k