环形缓冲器(ringr buffer),也称作圆形队列(circular queue),循环缓冲区(cyclic buffer),圆形缓冲区(circula buffer),是一种用于表示一个固定尺寸、头尾相连的缓冲区的数据结构,适合缓存数据流。
实现实例:
//这里定义圆形缓存器
function ringBuffer(limit = 10, overflowAction) {
let arr = new Array(limit)
let length = 0
let pushIndex = 0
let popIndex = 0
//放入圆形缓存区,当pushIndex的长度是limit的长度时,pushIndex归零,进行循环
const push = it => {
arr[pushIndex] = it
pushIndex = (pushIndex + 1) % limit
length++
}
//拿出popIndex的数据,并将该索引的值置为null
const take = () => {
if (length != 0) {
let it = arr[popIndex]
arr[popIndex] = null
length--
popIndex = (popIndex + 1) % limit
return it
}
}
//冲洗缓存区,拿出所有的数据,此时的圆形缓存区为空
const flush = () => {
let items = []
while (length) {
items.push(take())
}
return items
}
return {
isEmpty: () => length == 0,
//处理圆形缓存器溢出
put: it => {
if (length < limit) {
push(it)
} else {
let doubledLimit
switch (overflowAction) {
case ON_OVERFLOW_THROW: //禁止覆盖缓存区
throw new Error(BUFFER_OVERFLOW)
case ON_OVERFLOW_SLIDE: //循环覆盖缓存区
arr[pushIndex] = it
pushIndex = (pushIndex + 1) % limit
popIndex = pushIndex
break
case ON_OVERFLOW_EXPAND: //扩展缓存区
doubledLimit = 2 * limit
arr = flush()
length = arr.length
pushIndex = arr.length
popIndex = 0
arr.length = doubledLimit
limit = doubledLimit
push(it)
break
default:
// DROP
}
}
},
take,
flush,
}
}
这是redux-saga中的buffer源码,redux-saga采用了这种缓存模式