Действие прекращения запускается при помощи 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 и, вероятно, взгляну на наблюдаемый при редуксе.Если кто-то все еще хочет посмотреть на это, ответ никогда не теряется.