diff --git a/src/createStore.ts b/src/createStore.ts index 807e87d9cb..2560ad863e 100644 --- a/src/createStore.ts +++ b/src/createStore.ts @@ -6,7 +6,8 @@ import { StoreEnhancer, Dispatch, Observer, - ExtendState + ExtendState, + ListenerCallback } from './types/store' import { Action } from './types/actions' import { Reducer } from './types/reducers' @@ -119,8 +120,9 @@ export function createStore( let currentReducer = reducer let currentState = preloadedState as S - let currentListeners: (() => void)[] | null = [] + let currentListeners: Map | null = new Map() let nextListeners = currentListeners + let listenerIdCounter = 0 let isDispatching = false /** @@ -132,7 +134,10 @@ export function createStore( */ function ensureCanMutateNextListeners() { if (nextListeners === currentListeners) { - nextListeners = currentListeners.slice() + nextListeners = new Map() + currentListeners.forEach((listener, key) => { + nextListeners.set(key, listener) + }) } } @@ -197,7 +202,8 @@ export function createStore( let isSubscribed = true ensureCanMutateNextListeners() - nextListeners.push(listener) + const listenerId = listenerIdCounter++ + nextListeners.set(listenerId, listener) return function unsubscribe() { if (!isSubscribed) { @@ -214,8 +220,7 @@ export function createStore( isSubscribed = false ensureCanMutateNextListeners() - const index = nextListeners.indexOf(listener) - nextListeners.splice(index, 1) + nextListeners.delete(listenerId) currentListeners = null } } @@ -272,11 +277,9 @@ export function createStore( } const listeners = (currentListeners = nextListeners) - for (let i = 0; i < listeners.length; i++) { - const listener = listeners[i] + listeners.forEach(listener => { listener() - } - + }) return action } diff --git a/src/types/store.ts b/src/types/store.ts index 21bdbcce99..488092b2a2 100644 --- a/src/types/store.ts +++ b/src/types/store.ts @@ -91,6 +91,8 @@ export interface Unsubscribe { (): void } +export type ListenerCallback = () => void + declare global { interface SymbolConstructor { readonly observable: symbol @@ -198,7 +200,7 @@ export interface Store< * @param listener A callback to be invoked on every dispatch. * @returns A function to remove this change listener. */ - subscribe(listener: () => void): Unsubscribe + subscribe(listener: ListenerCallback): Unsubscribe /** * Replaces the reducer currently used by the store to calculate the state.