You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
importReact,{useState}from"react";constarr=Array.from(Array(3000)).map(v=>[Math.random().toString(36).substring(7),Math.random()]);exportdefaultfunctionApp(){const[data1,setData1]=useState("immutable");const[data2,setData2]=useState("mutable");consthandleR1=()=>{console.time("immutable in reduce");constr1=arr.reduce((r,v)=>({
...r,[v[0]]: v[1]}),{});console.timeEnd("immutable in reduce");setData1("r1 finish");};consthandleR2=()=>{console.time("mutable in reduce");constr2=arr.reduce((r,v)=>{r[v[0]]=v[1];returnr;},{});console.timeEnd("mutable in reduce");setData2("r2 finish");};return(<div><div><buttononClick={handleR1}>{data1}</button></div><div><buttononClick={handleR2}>{data2}</button></div></div>);}
水文一篇...
其实这里要讲两个事情, 但是由于这两个东西可以写的东西都不多, 所以就用一篇文章了. 另外这两个东西几乎没有任何关联性
window resizing
业务上碰到的一个需求, 我需要监听
window
在什么时候resizing
结束, 在结束的那一刻我可以做一个标记, 比如最简单的进行一次setState
错误思路
一开始没想太多, 直接写. 写到一半发现不对了. 代码可能长这样:
很明显, 最后的结果就是一旦开始
resize
,windowResizing
就会一直保持true
, 即使我已经停止了resize
. 原因也很简单,resize
这个事件只会去监听change
时候的变化, 至于什么时候stop
, 他没有暴露任何 API, 他只知道变了, 但不知道这个变了啥时候停止但我恰恰就需要知道啥时候停止
防抖
先考虑另外一种场景, 我需要监听
resize
时候window
的width
变化, 但我不需要在resize
发生每一帧都去监并显示变化, 这是一个高频率触发的事件. 比如resize
到一半的时候, 停顿了一下, 这个频率是比正常resize
频率低一些的, 那我在这个时候是可以去获得或者说监听到width
变化.实际上说了这么多就是要对
resize
事件做一个防抖(debounce
)...理解起来也不难, 这里我给了 200ms 的限制, 也就是说低于 200ms 速率的
resize
操作,handleResize
这个回调函数里的setWindowWidth
操作还没等到 200ms, 就被clearTimeout
掉了, 然后timerId
又存了最新的一次操作的id
, 只要resize
速率是低于 200ms 的, 那么一定是出现上一次操作还没来得及执行就被clear
掉,timerId
被(下一次)最新一次的操作给覆盖. 所以windowWidth
永远还是最初的,setState
也就不会被高频触发直到某次
resize
操作后有大于 200ms 的停顿, 这个时候setWindowWidth
等到了时间, 可以执行一次setState
, 虽然再开始resize
的时候timerId
还是被clear
掉, 但是setWindowWidth
已经执行过了, 因此不影响.总结就是上一次
resize
和 下一次resize
之间间隔在 200ms 以内, 限制对应操作, 否则允许操作函数执行解决方案
扯了很多防抖, 其实去监听
window
resize
什么时候停止, 也是类似的方案首先要明确, 什么时候才算
resize
停止, 我可以认为没有resize
事件后的 10s 算停止(有点长), 我也可以认为是 0.000001ms 之后算停止(太短了), 所以我还是用 200ms 作为界限, 上一次resize
和下一次resize
之间间隔在 200ms 以内的, 都算还在resizing
, 超过 200ms 的, 记为resize
停止了.代码如下:
从代码上来看,
windowResizing
这个状态是一直在true
和false
之间切换, 但false
状态是有延迟的. 所以可以模拟出resize
停止的那个状态reduce
这个函数也用的很多了, 面试也经常考让手写一个简易的.
这里想记录的是做项目时遇到的一个 immutable 或者 mutable 的写法问题, 由于真实项目的数据还要复杂和繁琐, 这里只做模拟实现
目标
用
reduce
将上面的二位数组转成下面这种格式二位数组里的数据至少有 3000 条
两种做法
直接看代码:
handleR1
和handleR2
分别是两种写法, 结果都是一样的, 对应 immutable 和 mutable. 我个人是倾向第一种. 但是第一种有一些性能问题这里我用
console.time
和console.timeEnd
分别记录两种操作所需要的时间, 第一种 immutable 写法的时间大致为 2000ms, 第二种 mutable 写法时间大致为 2ms, 2000 倍的差距...效果图如下:
点击 immutable 的按钮花了很久才显示结束, 卡顿非常明显, 而 mutable 的按钮秒结束...
所以 immutable 的写法有时候可能不一定那么好?
The text was updated successfully, but these errors were encountered: