Почему длина массива слушателей равна 3 вместо 2 в последнем файле console.log? - PullRequest
2 голосов
/ 16 апреля 2020

Я писал свою собственную маленькую версию Redux, чтобы понять, как она работает под капотом.

В приведенном ниже коде мне интересно, почему последний журнал консоли не дает ожидаемого результата.

Комментарий в коде четко описывает проблему. Помогите кому-нибудь -

function createStore(reducer) {
  let state;

  let listeners = [];
  const getState = () => state;

  const subscribe = listener => {
    listeners.push(listener);
    return () => {
      listeners = listeners.filter(thisListener => thisListener !== listener);
    };
  };

  const getListeners=()=>{
    return listeners
  }

  const dispatch = action => {
    state = reducer(state, action);
    listeners.forEach(listener => listener());
  };

  return {
    getState,
    subscribe,
    dispatch,
    listeners,
    getListeners
  };
}

// Create the store-
const store = createStore();

// Subscribing to store changes
store.subscribe(() => {
  console.log("The new state is: ", store.getState());
});

// To check the number of items present in listeners array
console.log("1. store.listeners",store.listeners.length)  // prints length- 1, as expected
console.log("1. store.getListeners",store.getListeners().length) // prints length- 1, as expected

store.subscribe(() => {
  console.log("State changes");
});

console.log("2. store.listeners",store.listeners.length) // prints length- 2, as expected
console.log("2. store.getListeners",store.getListeners().length) // prints length- 2, as expected

const unsubscribe= store.subscribe(() => {
  console.log("State changes");
});

console.log("3. store.listeners",store.listeners.length) // prints length- 3 as expected
console.log("3. store.getListeners",store.getListeners().length) // prints length- 3 as expected

unsubscribe()

console.log("4. store.listeners",store.listeners.length) // printed length- 3 ( Why not 2?)
console.log("4. store.getListeners",store.getListeners().length) // prints length- 2, as expected

1 Ответ

2 голосов
/ 16 апреля 2020

listeners.filter возвращает новый массив. Но объект, который вы вернули из createStore, всегда будет иметь начальную ссылку.

Вместо этого вы можете использовать splice для изменения массива на месте.

function createStore(reducer) {
  let state;

  let listeners = [];
  const getState = () => state;

  const subscribe = listener => {
    listeners.push(listener);
    return () => {
      listeners.splice(listeners.indexOf(listener), 1);
    };
  };

  const getListeners=()=>{
    return listeners
  }

  const dispatch = action => {
    state = reducer(state, action);
    listeners.forEach(listener => listener());
  };

  return {
    getState,
    subscribe,
    dispatch,
    listeners,
    getListeners
  };
}

// Create the store-
const store = createStore();

// Subscribing to store changes
store.subscribe(() => {
  console.log("The new state is: ", store.getState());
});

// To check the number of items present in listeners array
console.log("1. store.listeners",store.listeners.length)  // prints length- 1, as expected
console.log("1. store.getListeners",store.getListeners().length) // prints length- 1, as expected

store.subscribe(() => {
  console.log("State changes");
});

console.log("2. store.listeners",store.listeners.length) // prints length- 2, as expected
console.log("2. store.getListeners",store.getListeners().length) // prints length- 2, as expected

const unsubscribe= store.subscribe(() => {
  console.log("State changes");
});

console.log("3. store.listeners",store.listeners.length) // prints length- 3 as expected
console.log("3. store.getListeners",store.getListeners().length) // prints length- 3 as expected

unsubscribe()

console.log("4. store.listeners",store.listeners.length) // printed length- 3 ( Why not 2?)
console.log("4. store.getListeners",store.getListeners().length) // prints length- 2, as expected
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...