(
type: PubSubType,
channels?: string | Array<string>,
listener?: PubSubListener<T>,
returnBuffers?: T
)
| 222 | } |
| 223 | |
| 224 | unsubscribe<T extends boolean>( |
| 225 | type: PubSubType, |
| 226 | channels?: string | Array<string>, |
| 227 | listener?: PubSubListener<T>, |
| 228 | returnBuffers?: T |
| 229 | ) { |
| 230 | const listeners = this.listeners[type]; |
| 231 | if (!channels) { |
| 232 | return this.#unsubscribeCommand( |
| 233 | [COMMANDS[type].unsubscribe], |
| 234 | // cannot use `this.#subscribed` because there might be some `SUBSCRIBE` commands in the queue |
| 235 | // cannot use `this.#subscribed + this.#subscribing` because some `SUBSCRIBE` commands might fail |
| 236 | NaN, |
| 237 | () => listeners.clear() |
| 238 | ); |
| 239 | } |
| 240 | |
| 241 | const channelsArray = PubSub.#channelsArray(channels); |
| 242 | if (!listener) { |
| 243 | return this.#unsubscribeCommand( |
| 244 | [COMMANDS[type].unsubscribe, ...channelsArray], |
| 245 | channelsArray.length, |
| 246 | () => { |
| 247 | for (const channel of channelsArray) { |
| 248 | listeners.delete(channel); |
| 249 | } |
| 250 | } |
| 251 | ); |
| 252 | } |
| 253 | |
| 254 | const args: Array<RedisArgument> = [COMMANDS[type].unsubscribe]; |
| 255 | for (const channel of channelsArray) { |
| 256 | const sets = listeners.get(channel); |
| 257 | if (sets) { |
| 258 | let current, |
| 259 | other; |
| 260 | if (returnBuffers) { |
| 261 | current = sets.buffers; |
| 262 | other = sets.strings; |
| 263 | } else { |
| 264 | current = sets.strings; |
| 265 | other = sets.buffers; |
| 266 | } |
| 267 | |
| 268 | const currentSize = current.has(listener) ? current.size - 1 : current.size; |
| 269 | if (currentSize !== 0 || other.size !== 0) continue; |
| 270 | sets.unsubscribing = true; |
| 271 | } |
| 272 | |
| 273 | args.push(channel); |
| 274 | } |
| 275 | |
| 276 | if (args.length === 1) { |
| 277 | // all channels has other listeners, |
| 278 | // delete the listeners without issuing a command |
| 279 | for (const channel of channelsArray) { |
| 280 | PubSub.#listenersSet( |
| 281 | listeners.get(channel)!, |
nothing calls this directly
no test coverage detected