Redux-Saga как вызвать метод localStorage.clear в Saga

Я пытаюсь очистить все элементы, хранящиеся в localStorage, в методе Redux Saga. Но это работает не так, как ожидалось.

Теоретически, если я хочу вызвать функцию в Saga, нам нужно написать ее без скобок с ключевым словом call.

Итак, я попытался написать это с помощью yield call(localStorage.clear);, но он не удаляет элементы из LocalStorage. Если я добавил brackets () или без yeild & call, он будет работать и очищать элементы в LocalStorage, как и ожидалось.

export function* logoutUserSaga() {
try {
    const accessToken = yield call(AuthService.getAccessToken);
    yield call(AuthService.logoutUser, accessToken); 
    yield put(logoutUser.success());

    yield call(localStorage.clear); // not working

    //yield call(localStorage.clear()); // working
    //localStorage.clear(); // working

    yield put({ type: RESET_ALL_STATE });
}
catch (error) {
    yield put(logoutUser.failure({ errorMessage: error.statusText }));
}
}

export default function* watcherSaga() {
    yield takeLatest(authenticateUser.TRIGGER, authenticateUserSaga);
    yield takeLatest(logoutUser.TRIGGER, logoutUserSaga);
    yield takeLatest(getAccessToken.TRIGGER, getAccessTokenSaga);
}

Хотелось бы узнать, почему не работает функция вызова без скобок ().

Причина в том, что вызываемая функция недействительна и не возвращает никакого значения?
Всегда ли мы должны добавлять скобки, если мы хотим вызвать методы void?


person TTCG    schedule 03.08.2019    source источник
comment
Вам нужно использовать вызов только для асинхронных операций. local Storage.clear является синхронным, поэтому вы можете просто вызвать его напрямую   -  person Patrick Hund    schedule 03.08.2019


Ответы (1)


Причина, по которой он не работает, заключается в том, что функция localStorage.clear ожидает, что this будет равно localStorage. Это происходит автоматически при использовании обозначения localStorage.clear, но если у вас есть ссылка на функцию и вы вызываете ее без контекста, вы получите ошибку Illegal invocation. Это не имеет прямого отношения к сагам и может быть воспроизведено следующим образом:

  const clear = localStorage.clear;
  clear(); // throws an exception

Однако это имеет косвенное отношение к сагам, и именно так работает call. Если вы не укажете call, какой контекст он должен использовать при вызове функции, тогда у него нет другого выбора, кроме как вызвать его в глобальном контексте, вызывая это исключение. call имеет несколько вариантов параметров, позволяющих указать, чему this должно соответствовать. Например, вы могли бы сделать это:

yield call([localStorage, localStorage.clear]);

Вы можете увидеть другие варианты параметров, которые принимает вызов здесь: https://redux-saga.js.org/docs/api/


Другой вариант - просто не использовать call. Использование call имеет преимущества при попытке протестировать сагу и имеет то преимущество, что он работает как с сагами, так и с обычными функциями, но вы все равно можете сами вызывать обычные функции, если хотите.

person Nicholas Tower    schedule 03.08.2019