对前端对象池技术的学习笔记

今天看了一位叫飞叶的老师的视频,学习到了池化技术这一概念。对象池模式也是一种比较常见的设计模式了,通俗来说池化技术是为了提高应用性能和减少开销。比如公共食堂有取筷子的地方,那么放筷子的容器属于一个对象池,专门存放筷子这个"对象",每次人们需要用筷子的时候就在筷子盒里面拿,用完又放回去筷子盒(对象池),当食堂就餐人数较多时,筷子被拿完了,筷子盒现在空了,那么就需要买一些新的筷子(即创建新的对象)供人们使用,所有新的和旧的筷子被使用完后又放回筷子盒。所以说对象池集中管理一些具有相同规则的同质对象,它们是具有相同的逻辑状态的,比如所有筷子都是有相同的功能,而不能把餐盘这种“对象”和筷子放在一起。
一般对象池技术应用场景有连接池、内存池等等。连接池一般多见于JDBC、Redis连接池、http连接池等等。那么前端对象池技术的应用核心也是为对象复用,比如React也使用到了对象重用池的优化策略和cocos引擎 Cocos Creator 使用对象池
比如一些小游戏类似消灭星星,那么这些星星需要被反复多次的生成和消除,频繁地生成和销毁节点需要消耗大量性能,所以采用对象池技术把消除的星星存起来,需要生成时再从池子中拿即可。

小例子

先返回一个星星工厂对象,它里面有一个星星对象池,一个创建星星对象方法,一个回收星星对象方法。

var starFactory = (function(){
    // 星星对象池
    var starPool = [];
    return {
        createStar(){
            // 当星星对象池为空时,创建新的星星并返回
            if(!starPool.length){
                // 用一个div节点比作星星节点
                const starDom = document.createElement('div');
                document.body.appendChild(starDom);
                return starDom;
            }else{
                // 当星星对象池不为空,直接用池子里的节点
                starPool.pop();
            }
        },
        // 回收对象到对象池
        recoverStar(starDom){
            return starPool.push(starDom);
        }
    }
})()

游戏开始,首批星星节点先被创建并初始化,并且收集新的节点。

var divArr = [];
var starArr = ['黄色星星', '蓝色星星'];
for(let i=0;i<starArr.length;i++){
    // 创建新节点
    let starDiv = starFactory.createStar();
    // 并初始化节点
    starDiv.innerHTML = starArr[i];
    // 收集新节点
    divArr.push(starDiv);
}

当部分星星节点被消除时,又需要产生一些新的星星节点,此时把收集的新节点回收到对象池,这时可以先再池子拿对象,等对象池为空时再创建新节点,同时再收集它们。

for(let i=0;i<divArr.length;i++){
    // 先把上一次收集的新节点全部回收到池子
    starFactory.recoverStar(divArr[i]);
}
var starArr2 = ['绿色星星', '紫色星星', '红色星星'];
for(let i=0;i<starArr2.length;i++){
    // 这次创建节点时,因为上一次有两个节点被回收了,
    // 所以部分可以直接在池子拿不需要create元素,部分需要新创建
    let starDiv = starFactory.createStar();
    starDiv.innerHTML = starArr[i];
    // 再次收集新创建的节点
    divArr.push(starDiv)
}

上述每一次都是先把上一次收集的结果回收一下,再用工厂对象给创建出来,那么可以提取出代码块

var divArr = [];
var SAR = () => {
    for(let i=0;i<divArr.length;i++){
        starFactory.recoverStar(divArr[i]);
    }
    var starArr2 = resArr;  //接口返回的数据
    for(let i=0;i<starArr2.length;i++){
        let starDiv = starFactory.createStar();
        starDiv.innerHTML = starArr[i];
        divArr.push(starDiv)
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值