Skip to content

Unsubscribe a listener inside a listener has side-effects on other listeners #461

Closed
@arian

Description

@arian

Unsubscribing a listener inside a listener, will splice the listeners array in the store of createStore, while looping over that array using forEach in dispatch.

For example the following program fails:

import assert from 'assert';
import {createStore} from 'redux';

var store = createStore(() => []);

var countA = 0;
var countB = 0;
var countC = 0;

var unsubA = store.subscribe(() => {
    countA++;
});

var unsubB = store.subscribe(() => {
    countB++;
    unsubB();
});

var unsubC = store.subscribe(() => {
    countC++;
});

store.dispatch({type: 'X'});
store.dispatch({type: 'Y'});

console.log(countA, countB, countC);

assert.equal(countA, 2, 'countA');
assert.equal(countB, 1, 'countB');
assert.equal(countC, 2, 'countC');

countC is 1, but it should be 2.

A fix for this problem would be to copy the array before doing the forEach in the dispatch function, for example:

listeners.slice().forEach(listener => listener());

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions