MO
MO
最近采(mian)访(shi)了几个地球星人,发现他们都不了解节流和防抖,简直是有点不可思议 这对我们游戏星人来说简直是日常了 ## 什么是节流? 『技能CD』了解一下?不要和我扯什么setTimeout,咱都听不懂,那是你们地球星人的词 为什么给角色加技能冷却时间?还不是因为太强了,为了削弱,当然得加了,不止可以加CD,我们还可以再加个蓝条  ## 什么是防抖 不知道为什么你们用这么别扭的词,在我们眼里,这就是打出『僵直』 如果对面打出一套连招,让我们不停地进入『僵直』状态,我们就没法行动了 当然僵直也是有持续时间的,假如持续时间只有0.1s,0.1s的僵直时间过后,那就可以开始行动了。但是如果对面的僵直效果持续时间很长,我们可能就会陷入对面的无限连招中,比如僵直时间快到了,结果对面又啪啪啪给你来了一套技能,然后你就一直没法行动,这就很尴尬  ### 名词解释 『技能CD』:玩家在使用某项技能后所需等待后方能再次使用的最短时间 『僵直』:一种异常状态,僵直下目标无法做出任何动作
## 楔子 大家有没有想过,为什么通常情况下发送一个ajax请求是一次异步调用? 原因很明显,**因为它慢**! **JavaScript是单线程模型,只有一个调用/执行栈,一次只能执行一个任务,一个io操作执行很慢,如果选择等待它执行结束,那么调用者很久才能出栈,后续的代码都会被阻塞** 可能你会说了,你胡说,你说JavaScript是单线程的,但后面不是出来个worker么,胡说的话信不信我小拳拳捶你胸口 那我问你,一个页面当中嵌个iframe,然后拿postMessage和iframe通信,是不是多线程啦,毕竟iframe里面还有代码在运行呢 而且worker的api只在浏览器中有,虽然nodejs也准备实现worker api了,但那是另一码事 ### 回到主题 是什么让JavaScript在单线程的情况下做到non-blocking IO的呢? 这里**不得不**提一个东西,**Event Loop**,事件循环 你可能之前没听过这货,但是假如我说 - 回调地狱就是它引起的 (误 - setTimeout( fn, 0 )并不是立马执行也是它引起的(误 你是不是会狠狠记住它呢? 为了实现non-blocking IO,有了Event Loop,才有了callback形式的调用方式 因为需要等主线程空闲,所以setTimeout设定的duration其实只是保证了等待的最小时间,并不是准确的 ##...
重构的核心目的其实是**减少后期的维护成本** 复用性、高可扩展性这些都是基于这个目的衍生出来的一些副产物 ### 下面是最近几次重构下来的一些总结 - 根据语义提取基本不变的部分,提高可维护性 - 消除this的使用,this的使用对复用和后期维护很不利 - 杜绝在函数中对外部变量进行引用,会让函数产生副作用 - 函数入参和出参设计合理,提高复用性的同时,从函数的职责、语义出发,思考入参是否冗余,函数职责是否过重,函数名是否存在歧义或误导,针对这些点,可以做些简化函数入参,拆分多个函数等处理 - 适当地进行抽象,可以减少一些代码量和维护成本 - 区分public和private,一个类不对外暴露的方法全部用`_name`的形式,如果不区分公有方法和私有方法,下次就无法得知哪些方法被外部使用了,会极大地增加改造成本,公用方法应该从一开始就保持稳定,内部私有方法随意改写 - 不要想着一个类解决所有问题,在设计的时候可以考虑组合类和继承类 - 模块划分和设计应当合理,不要什么都往utils里面塞,一些业务相关,无法公用或者只会用到一次的,在业务内部封装即可,不要拆到utils里面,不然下次你加到utils里面的方法被别人使用了,你再想改造就很困难了 - 保证完整的生命周期,比如有了init,也提供一个destroy,这才是较合理的设计 另外说下提高架构/重构能力的方式,不一定要去读源码,**去读一些库的文档,或者插件的开发文档**也是很有帮助的,比如我之前写过grunt、gulp、webpack、postcss、atom、rollup等的插件、chrome扩展、chrome app、electron应用,从里面可以学到很多api设计方面的东西,和一些复杂架构的设计,这些东西浅浅地看下源码是体会不到的
### pure是什么 **又一个组件库的轮子** > 仓库:https://github.com/fengzilong/pure > 文档兼演示:https://fengzilong.github.io/pure ### pure诞生记 pure使用了很多新的css特性,比如flex、vh等等  所以并不打算支持IE低版本🤷♂️ ### 聊一聊设计细节 #### 从 Pure.modal 讲起 或许你会问,为什么要支持这种命令式的书写方式呢?纯粹的声明式写法不好么? 答案自然是为了效率 这种形式的调用可以让你流畅地写完逻辑,而不需要写一堆控制Model显隐的逻辑,导致中断思路去修改模板代码。 从实践的角度去说,我们使用弹窗只是为了给用户一些提示,或者向用户索要一些信息,声明式也好,命令式也好,我们关心的只是动作的结果(通知了用户或者得到了用户的输入),而不是过程和形式,并不需要严格遵守声明式的写法,适当变通 #### Select/Option 再来说下拉框组件,Select传入options属性值不就好了么,为什么还要单独设计一个Option组件呢? 考虑下面这样的场景,如果从服务端拿到的数据是下面这种格式 ``` js [ {...
原文:https://medium.com/@cramforce/designing-very-large-javascript-applications-6e013a3291a3 视频:https://www.youtube.com/watch?v=ZZmUwXEiPm4 译文:https://zhuanlan.zhihu.com/p/35929167 ## 去中心化 > I want to give a few examples of this general idea that you want to avoid central configuration of your application at all cost,...
# 剧本 ### 时间 ### 地点 野外,有一排 每棵树上都长了一颗 > 观众:mmp,这是椰子树,你告诉我长了苹果?! > 导演:我说是就是 ### 出场人物 主角: 你 配角: 猴子 ### 故事开始了 你看到了这排🌴,然后突然想吃树上的🍎,但你不会爬树啊 环绕四周一看,诶,远处有只猴子诶 --- 你:猴子🐒,你能帮我把苹果摘下来么? 会说话的猴子:我为什么要帮你摘啊,你能给我什么? 你眉头一皱,挠了挠头 “我给你香蕉🍌可以么?” 会说话的猴子:成交了👌 ```js function...
单文件组件这点一开始是由riot实现的,刚好自己用的上一个视图层框架就是这个,所以对这种写法可能会觉得更加亲切吧,后来vue也实现了单文件组件的形式,不过借助webpack的各种特性,更加强大~ ### 简单总结下单文件组件的优点 - 约定了一种统一的组件组织形式,便于组件分发 > 单文件组件可以跨项目使用而不用担心不同项目间的架构差异(前提都是用的`*.vue`),不同工程对于html、js、css的文件组织方式可能会有差异,也可能使用了不同的css预处理器,想要完成迁移可能会有成本。但现在这些都统一了,你可以在组件内部使用任意的css预处理器,webpack抹平了这种差异(增加相应的loader即可),迁移的成本基本只剩下单个文件的复制粘贴 - 频繁地在js、html、css中切换,对开发体验不利 > 这是vue作者的[原话](https://vuejs.org/2015/10/28/why-no-template-url/): > But is splitting your JavaScript code and the template really the best way? For a Vue.js component, its...
### 一些原则 - **视觉元素和状态的归属** 其中也涉及了语义 - **独立性** 是否可以从主逻辑中独立出来,使用组件封装/隐藏实现细节,减少主逻辑中不必要的代码 - **抽象** 一些有共同特征的提取出来,比如页面中用到的Iocn - **语义** 一些语义有明确界限的,在顶层就区分出来,比如Sidebar、Main,减少顶层出现一些"杂质"(模板的碎片?)和额外的逻辑,**这就像圈神经猫的游戏一样,不断从语义层面划分组件界限,方便缩小定位bug的范围,直接一锅端会导致逻辑很分散**,这种拆分方式对后期的维护也有好处,直接把某个顶层组件删除,就可以快速地移除某一块的功能,用新的组件替换上来,这也是数据驱动视图带来的好处,如果绑个事件都和DOM强耦合就做不到这点了 > 这点类似电脑的制造,往往一台电脑的cpu、显示器等等都是来自不同的厂商,如果每个厂商都负责整机的制造,可能电脑各方面的提升也没这么快了,拆分出来之后能够专注于实现组件自身的功能 ### 其他 时间允许的情况下,组件尽量拆分得细些,当然拆的时候也要注意,并不是直接把页面给"捋平" ```html ``` 这种一马平川的写法,并不推荐(当然和页面复杂程度有关,简单的页面这么写就好啦) 比如,可以思考下 > A下面是不是可以分出更细的组件 > B中的内容需不需要用`{#inc this.$body}`的方式引入 > CDE在整体的语义上是不是一体的...
天赋或许是存在的 一个好的程序员有一些特质,懒(don't repeat yourself)、想象力(创造力)等等 换句话说天赋可能就是这些特质的积累,或者说有些人天生适合做一个程序员 每个人都有特质/天赋,只是可能表现的途径不一样而已 比如一个人文档写得好,菜烧得好,照片拍得好,画画画得好,这些都是天赋 但这些特质并不是成为一个优秀程序员的全部条件 比如英语水平、学习方式、行为习惯和处事态度可能都是影响因素,所以没必要沮丧天赋什么的,大部分都是可以后天培养的 你只要保证自己走在了正确的路上就好,go go go 就像以前看到的一篇文章,一个老头在很大年纪的时候突然发现了自己的数学天赋,成为了一个数学家orz,忘了是谁了,可能你只是还没有挖掘出自己的才能而已
面向"演员"编程
猜猜我要说什么? 其实这个想法来源于redux中的`Presentational/Dumb components`,翻译过来就是`展现型组件`,或者`木偶组件` 这些组件类似函数式编程中的纯函数,或许叫他们"纯组件",你们会更容易接受,他们接收props,表现出可预测的行为,就像你手里的调色盘,每个组件都有各自的色彩,我们可以拿他们画出各种作品 想要深入了解的话,可以阅读[这篇文章](https://medium.com/@dan_abramov/smart-and-dumb-components-7ca2f9a7c7d0#.qqtjb6z2p) 这里姑且把他们比作演员 想要写好一个程序,你需要先有一批好"演员",并了解每个"演员"的特长,以及适合演的角色 他们有演技,但却不限于演某个特定的角色,换部电影照样可以继续演 他们的演技体现在可以准确的表达自己的状态,比如喜、怒、哀、乐,甚至同一种状态还可以有各自微妙的变化,导演(我们)在选择一个演员的时候,需要考究一个演员的演技,那么如何去评定呢? 我们需要有一段剧本(或者说台词),这段剧本可以节选自即将开拍的电影 接下来我们就会让演员自己去理解这段剧本,并用自己的方式演绎它,借此来衡量一个演员和角色的匹配程度,以及了解每个演员的特点(下一部电影说不定需要这种演员哦) 如果没有这个过程,每个演员都像是一个黑盒子,我们就没办法得知演员和角色的匹配程度,而有了这个过程,就算原来的导演罢工了,换了个新导演,也可以很快地接手!比如,"哦,这家伙一看就是演坏蛋的!" 所以类似[react-storybook](https://github.com/storybooks/react-storybook)和[vue-play](https://github.com/vue-play/vue-play),就很好理解他们的作用啦,可以评定一个演员是否符合我们的要求,同时帮助我们了解每个”演员“的特点 基于regular便有了下面这个项目 [regular-play](https://github.com/fengzilong/regular-play) 这和单纯的文档还是有差别的,你只需要写这样一段[剧本](https://github.com/fengzilong/regular-play/blob/master/example/input.play.js),就可以"演"给别人看啦 [戳我查看](https://fengzilong.github.io/regular-play) (regular-play中的play意指"扮演") 说了这么多,其实就是一种快速展示组件的方式,可以在一个沙箱中查看各个组件的各种状态,同时能很快地知道每个组件是长什么样的,定位组件功能,下次看到某个组件或某个功能,可以一眼认出来,我在哪里见过你! 而常规的方式可能是从页面入手,先打开某个页面,产品说要改某个东西,进行n步操作才能找到自己想找的,有时候看到了某块区域,也不知道对应的是哪个组件(有时候压根不是一个独立的组件,可能是js动态生成的),就算找到了对应的组件,也不知道他有哪些状态,不同的状态长什么样,仍然是一个黑盒子 常规的方式其实不符合一个人正常的认知习惯,先看到功能,再推测修改哪块代码,就好像在推理案件,然而并没有事先收集线索,完全是在瞎蒙,碰巧看到了!对,凶手就是你好了orz,然后瞎改一通,完事