Redux Saga прекращает действие по неизвестной причине - PullRequest
1 голос
/ 01 июля 2019

Действие прекращения запускается при помощи redux-saga по неизвестной причине на сервере (SSR), и я не могу понять, почему.
Это действительно проблема блокировки, и я не знаю, как ее отладить...

app.get("*", (req, res, next) => {
    if (req.originalUrl === '/reload/reload.js') return next();
    console.log('router hit');
    const store = configureStore();

    let htmlPath = config.get('iso.htmlRoot');

    fs.readFile(htmlPath, "utf8", function(err, template) {

        const context = {};

        console.log('before saga middleware is run');
        store.runSaga(sagas).toPromise().then(() => {
            console.log('saga middleware callback');
            const preloadedState = store.getState();
            const html = renderer(template, req.path, context, store);
            const strPreloadedState = JSON.stringify(preloadedState).replace(/</g, '\\u003c');

            console.log('preloadState', strPreloadedState);
            const htmlWithPreload = html.replace('{preloadedState}', strPreloadedState);

            console.log('*********  wtf  ********');
            res.set('content-type', 'text/html');
            res.send(htmlWithPreload);
            res.end();

        }).catch((e) => {
            console.log(e.message);
            res.status(500).send(e.message)
        });
        console.log('first renderer');

        renderer(template, req.path, context, store);

        store.close();

    });
});

store.close запускает событие END, поэтому между запросами AFAIK действительно не должно быть проблем.

У меня есть монитор на моем промежуточном программном обеспечении redux-saga, и я заметил, что есть событие завершения:

store initiated
before saga middleware is run
event rootSaga started { effectId: 81, saga: [GeneratorFunction: rootSaga], args: [] }
fetch gists saga start
watch effect id 85
watch effect @@redux-saga/TERMINATE --> why?? 

Моя сага очень проста:

import { all, call, put, fork, takeLatest } from 'redux-saga/effects';
import fetch from 'isomorphic-fetch';

import {
  FETCH_GISTS_REQUESTED,
  FETCH_GISTS__SUCCEEDED,
  FETCH_GISTS__FAILED,
} from './GetTrendingActions';

export const fetchUrl = () => fetch('https://api.github.com/gists', {
  method: 'get',
  headers: {
    Accept: 'application/json',
    'Content-Type': 'application/json',
  },
}).then((response) => {
  if (!response.ok) {
    throw new Error();
  }

  return response.json();
});

export function* fetchGists() {
  console.log('test');
  try {
    const gists = yield call(fetchUrl);
    yield put({
      type: FETCH_GISTS__SUCCEEDED,
      payload: {
        gists: gists.map(gist => ({
          id: gist.id,
          title: gist.description || 'pas de titre',
        })),
      },
    });
  } catch (error) {
    yield put({
      type: FETCH_GISTS__FAILED,
      payload: error,
    });
  }
}

export function* fetchGistsSaga() {
  console.log('fetch gists saga start');
  var task = yield takeLatest(FETCH_GISTS_REQUESTED, fetchGists); --> Something going wrong here 
  console.log('saga not finished');
}

export default function* rootSaga() {
  yield all([
    fork(fetchGistsSaga)
  ]);
}

Я опубликовал свою кодовую базу на Github здесь: https://github.com/kimgysen/zwoop-website

Вы можете запустить ее, используя:

npm install 
npm run start:iso:dev

или в Windows:

npm run:start:iso:dev:win 

Когда выЗапустите код, сага будет работать нормально при первом запуске, но при обновлении страницы обратный вызов саги-наблюдателя не будет работать так, как вы ожидаете.
Есть идеи?

Компонент Trending инициирует запрос на получение удаленных списков (который я добавил в качестве тестового API).Я не имею ни малейшего представления о том, почему наблюдатель саги отлично работает при начальной загрузке страницы, но не при последующих запросах.

Извините, если вопрос не так уж и ясен.Если вы запустите пример, вы увидите.Спасибо за совет.

Редактировать:
Я не добился большого прогресса после долгих экспериментов, и это начинает становиться болью.
При печати rootSaga, которую промежуточное программное обеспечение саги использует для раскруткигенераторы, я получаю следующий вывод:

before saga middleware is run function rootSaga() {
  return _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_0___default.a.wrap(function rootSaga$(_context3) {
    while (1) {
      switch (_context3.prev = _context3.next) {
        case 0:
          _context3.next = 2;
          return Object(redux_saga_effects__WEBPACK_IMPORTED_MODULE_1__["all"])([Object(redux_saga_effects__WEBPACK_IMPORTED_MODULE_1__["fork"])(fetchGistsSaga)]);

        case 2:
        case "end":
          return _context3.stop();
      }
    }
  }, _marked3);
}

Я использую "@babel/plugin-transform-runtime": "^7.4.4" и в .babelrc:

{
  "presets": ["@babel/preset-env", "@babel/preset-react"],
  "plugins": ["@babel/plugin-syntax-dynamic-import", ["@babel/plugin-transform-runtime", {
    "regenerator": true
  }]]
}

Мне очень интересно, может ли это иметь какое-либо отношение кпроблема, но это выстрел в темноте.
Однако я не могу отладить код сервера (скомпилированный код веб-пакета) с помощью Node devTools, поскольку скомпилированный код веб-пакета использует eval для всех своих операторов.

Я снова обращаюсь к моему репозиторию github, потому что это может быть слишком трудно решить иначе: https://github.com/kimgysen/zwoop-website
Я исправил проблему favicon.ico.
Также обратите внимание, что вам, возможно, придется начать:npm run start:iso:dev во второй раз, потому что условие гонки, которое мне еще предстоит исправить (или альтернативная сборка и запуск вручную сервера и клиента).Но в противном случае все должно работать без сбоев.
Обратите внимание, что на клиенте все работает так, как ожидалось, поэтому это действительно проблема только для рендеринга сервера.

Таким образом, сага работает, как и ожидалось, при первом рендеринге, а затем все последующие серверные рендеры не могут вызвать сагу-наблюдатель.Пожалуйста, порекомендуйте.

Редактировать 2:

В конце я не стал вдаваться в подробности.Redux-saga, похоже, хорошо работал на клиенте, но мне не удалось заставить его работать на SSR.
Я уже решил изучить RxJS и, вероятно, взгляну на наблюдаемый при редуксе.Если кто-то все еще хочет посмотреть на это, ответ никогда не теряется.

...