响应表达异常行为+下一个+对并发请求做出反应

时间:2019-03-25 18:08:27

标签: node.js reactjs express next.js

我有一个运行ExpressJS,Next和React的Node应用程序,该应用程序根据收到的标头动态加载不同的布局。该标头由Nginx在虚拟主机中设置。因此,想象一下必须加载同一应用程序的3个不同域,但是每个虚拟主机在此标头中都有一个不同的值,因此这是应用程序读取并返回正确布局的内容。

此方法将按预期工作,直到此标头中具有不同值的2个请求同时到达。发生这种情况时,其中一个的响应可能会完全或部分与另一个重叠。

我知道app.local和request.local的功能可以隔离请求/响应,但是玩了之后,它不能解决我的问题,或者我使用的方式错误。

在此链接上,您可以看到应用程序的软件架构概念(简化)。如果要重现该错误,则必须使用此标头设置2个具有不同值的虚拟主机,然后一次加载两个域:

https://codesandbox.io/s/zmoq4q3mp

任何帮助将不胜感激。

非常感谢您。

1 个答案:

答案 0 :(得分:1)

问题很简单,您要将当前模板分配给BeforeEach,这是整个应用程序共享的单例,它不是该请求唯一的。

因此,基本上,所有请求都在修改同一个config.layoutTpl对象,这就是您遇到问题的原因。使用并发时,不能使用“全局变量”,否则会遇到此类问题。

您必须将数据从config传递到_document.js,或直接在_app.js中获取模板,这是您当前唯一使用它的地方。

即使在下一步如何传递数据方面可能有更好的方法,也可以使用以下方法。

您需要做的而不是将模板分配给_document.js,而是将其分配给config,这对于每个请求都是唯一的。

_app.js

ctx

_document.js

export default withRedux(initStore)(
  class MyApp extends App {
    static async getInitialProps({ Component, ctx }) {

      let layoutTpl = null;
      if (ctx.req && !process.browser) {
        const { layouttpl } = ctx.req.headers;
        layoutTpl = layouttpl;
      }

      // Assign the current template, to the context
      // This is unique for this specific request
      ctx.layoutTpl = layoutTpl || config.layoutTpl;

      return {
        pageProps: Component.getInitialProps
          ? await Component.getInitialProps(ctx)
          : {}
      };
    }

    /* ... */
}