Redux传奇终止动作因未知原因触发

时间:2019-06-30 23:38:34

标签: reactjs redux redux-saga

由于服务器(SSR)上的未知原因,redux-saga触发了终止操作,我不知道为什么。
这确实是一个阻碍性的问题,我不知道如何进一步对其进行调试...

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 

在运行代码时,saga在第一次运行时可以正常工作,但是在刷新页面时,saga watcher回调未按预期运行。
任何想法?

趋势组件将触发获取远程摘要的请求(我已将其添加为测试api)。我不知道为什么saga观察器可以在初始页面加载时正常工作,而不能在后续请求上正常运行。

很抱歉,问题还不清楚。如果运行示例,您将看到。 感谢您的建议。

编辑:
经过大量的实验,我没有取得太大的进步,这开始变得很痛苦。
在打印saga中间件用来启动生成器的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);
}

我在{babelrc中使用"@babel/plugin-transform-runtime": "^7.4.4"

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

我强烈想知道这是否与问题有关,但这是黑暗中的镜头。
但是,我无法使用Node devTools调试服务器代码(由Webpack编译的代码),因为已编译的Webpack代码对其所有语句均使用eval

我再次引用我的github存储库,因为否则可能很难解决:https://github.com/kimgysen/zwoop-website
我修复了favicon.ico问题。
另请注意,您可能必须重新开始npm run start:iso:dev,因为我尚未解决的竞争状况(或替代性的构建并手动运行服务器和客户端)。但是它似乎应该可以正常工作。
请注意,在客户端上,一切都按预期工作,因此,这实际上只是服务器渲染的问题。

因此,传奇在第一个渲染上可以按预期工作,然后所有后续服务器渲染均无法调用观察者传奇。请指教。

编辑2:

最后我没有进一步研究。 Redux-saga在客户端上似乎运行良好,但我无法使其在SSR上正常运行。
我已经决定学习RxJS,并可能会研究redux-observable。如果仍然有人愿意看这个问题,提供答案就永远不会丢失。

0 个答案:

没有答案