在React中,使用到pool的地方并不少,比如
SyntheticEvent.js
中使用事件对象池,来创建销毁事件。ReactChild.js
使用child对象池,React.Children.forEach
来遍历子节点。
使用对象池来创建数据,可以很好地帮助我们创建那些需要频繁创建销毁的元素,并在性能上做一部分优化。
举例
我们使用Marker来标记地图上的点
参考
React.16.6.0
中SyntheticEvent.js
创建事件池的写法
定义Marker对象
function Marker(x, y, containerInfo) {
this.x = x
this.y = y
this.containerInfo = containerInfo
}
Marker.prototype.destroy = function () {
this.x = null
this.y = null
this.containerInfo = null
}
Marker.prototype.show = function () {
console.log(`x: ${this.x} y:${this.y} containerInfo:${this.containerInfo}`)
}
定义对象池相关
// 对象池大小
const MARKER_POOL_SIZE = 10
// 从pool中得到一个marker对象
function getPooledMarker(x, y, containerInfo) {
const MarkerConstructor = this
if (MarkerConstructor.markerPool.length) {
const instance = MarkerConstructor.markerPool.pop()
MarkerConstructor.call(instance, x, y, containerInfo)
return instance
}
return new MarkerConstructor(x, y, containerInfo)
}
// 归还一个marker对象到pool中
function releasePooledMarker(marker) {
const MarkerConstructor = this
if (marker instanceof MarkerConstructor === false) {
throw Error() // 当前marker不是由其创造,错误提示
}
marker.destroy()
if (MarkerConstructor.markerPool.length < MARKER_POOL_SIZE) {
MarkerConstructor.markerPool.push(marker)
}
}
// 向Marker上挂载对象池的方法
function addMarkerPoolingTo(MarkerConstructor) {
MarkerConstructor.markerPool = []
MarkerConstructor.getPooled = getPooledMarker
MarkerConstructor.release = releasePooledMarker
}
// 将对象池应用到Marker上
addMarkerPoolingTo(Marker)
使用方式
这里手动释放marker,即
marker = null
// 未使用对象池
let marker1 = new Marker(1, 1, 'container1')
marker1.show()
marker1.destroy()
marker1 = null
// 使用对象池
let marker2 = Marker.getPooled(2, 2, 'container2')
marker2.show()
Marker.release(marker2)
marker2 = null