hw_19_01 _1.html 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. <header>reducers</header>
  2. <body>
  3. <div id="testDiv">
  4. Test
  5. </div>
  6. <script>
  7. function promiseReducer(state = {}, action) { // диспетчер обработки
  8. if (action) {
  9. if (action.type === 'PROMISE') {
  10. let newState = { ...state };
  11. newState[action.name] = { status: action.status, payload: action.payload, error: action.error };
  12. return newState;
  13. }
  14. }
  15. return state;
  16. }
  17. function createStore(reducer) {
  18. let state = reducer(undefined, {}) //стартовая инициализация состояния, запуск редьюсера со state === undefined
  19. let cbs = [] //массив подписчиков
  20. const getState = () => state //функция, возвращающая переменную из замыкания
  21. const subscribe = cb => (cbs.push(cb), //запоминаем подписчиков в массиве
  22. () => cbs = cbs.filter(c => c !== cb)) //возвращаем функцию unsubscribe, которая удаляет подписчика из списка
  23. function dispatch(action) {
  24. if (typeof action === 'function') { //если action - не объект, а функция
  25. return action(dispatch, getState) //запускаем эту функцию и даем ей dispatch и getState для работы
  26. }
  27. const newState = reducer(state, action) //пробуем запустить редьюсер
  28. if (newState !== state) { //проверяем, смог ли редьюсер обработать action
  29. state = newState //если смог, то обновляем state
  30. for (let cb of cbs) cb() //и запускаем подписчиков
  31. }
  32. }
  33. return {
  34. getState, //добавление функции getState в результирующий объект
  35. dispatch,
  36. subscribe //добавление subscribe в объект
  37. }
  38. }
  39. function actionPromise(name, promise) {
  40. return async function Exec(dispatch) {
  41. dispatch(actionPending(name)) //сигнализируем redux, что промис начался
  42. try {
  43. const payload = await promise //ожидаем промиса;
  44. dispatch(actionFulfilled(name, payload)); //сигнализируем redux, что промис успешно выполнен
  45. return payload //в месте запуска store.dispatch с этим thunk можно так же получить результат промиса
  46. }
  47. catch (error) {
  48. dispatch(actionRejected(name, error)) //в случае ошибки - сигнализируем redux, что промис несложился
  49. }
  50. };
  51. }
  52. const actionPending = (name) => ({ type: 'PROMISE', name: name, status: 'PENDING' });
  53. const actionFulfilled = (name, payload) => ({ type: 'PROMISE', name: name, payload: payload, status: 'FULFILLED' });
  54. const actionRejected = (name, error) => ({ type: 'PROMISE', name: name, error: error, status: 'REJECTED' });
  55. const store = createStore(promiseReducer);
  56. store.subscribe(() => {
  57. console.log(store.getState())
  58. });
  59. store.dispatch(actionPromise('luke', fetch("https://swapi.dev/api/people/1").then(res => res.json())))
  60. //let execFunc = actionPromise({ name: "auth", promise: signIn("test457", "123123", "http://shop-roles.node.ed.asmer.org.ua/graphql") });
  61. // store.dispatch(execFunc);
  62. /*
  63. const actionPending = () => ({ type: 'PROMISE', status: 'PENDING' })
  64. const actionFulfilled = payload => ({ type: 'PROMISE', status: 'FULFILLED', payload })
  65. const actionRejected = error => ({ type: 'PROMISE', status: 'REJECTED', error })
  66. store.subscribe(() => console.log(store.getState()))
  67. store.dispatch({ type: 'COUNTER_INC' })
  68. store.dispatch({ type: 'BOOLEAN_SET' })
  69. store.dispatch({ type: 'COUNTER_INC' })
  70. store.dispatch({ type: 'BOOLEAN_TOGGLE' })
  71. store.dispatch({ type: 'COUNTER_DEC' })
  72. store.dispatch({ type: 'ДИЧЬ' }) //не вызывает подписчика
  73. */
  74. </script>
  75. </body>