1

我试图通过屈服于允许其他服务器请求查看的事件循环来使 React 成为更好的公民,renderToString例如renderToStaticMarkup

const React = require('react');
const { renderToNodeStream } = require('react-dom/server');

// Wrap `renderToNodeStream` in promise
const renderToStringAsync = node => {
  return new Promise((resolve, reject) => {
    let body = '';
    const stream = renderToNodeStream(node);
    // NOTE: we're turning the tap on full blast here, but I still expected it to yield
    stream.on('data', chunk => {
      console.log('Received chunk');
      body += chunk.toString();
    });
    stream.on('error', ex => {
      reject(ex);
    });
    stream.on('end', () => {
      resolve(body);
    });
  });
};

setTimeout(() => {
  console.log('Yielded to event loop');
}, 0)
await renderToStringAsync(largeRootNode);

我期待这个:

// Expect:
// Received chunk
// Yielded to event loop
// Received chunk
// Received chunk
// Received chunk
// Received chunk
// Received chunk
// Received chunk
// Received chunk
// Received chunk
// Received chunk

但我实际上得到了这个:

// Actual:
// Received chunk
// Received chunk
// Received chunk
// Received chunk
// Received chunk
// Received chunk
// Received chunk
// Received chunk
// Received chunk
// Yielded to event loop

我想知道它是否与.on('data'); 我知道它不能管理背压,但我一直认为它是异步的?

注意:我没有将响应传递给客户端,因为我需要等待渲染完成才能确定状态代码;我只是想用来renderToNodeStream改进 node.js 中的协作多任务处理)

4

1 回答 1

2

Promise 执行器是同步执行的,ReactDOMNodeStreamRenderer 也是如此。ReactDOMNodeStreamRender的_read方法没有异步组件,将按照Node 中的方法契约同步调用。

简而言之,这里的整个代码块是同步执行的,不涉及同步。流接口只是为它提供了异步执行的可能性,并且还使得管道到确实异步写入的流变得稍微容易一些。

需要注意的是,流接口本质上不会使任何操作异步!

于 2020-06-28T12:49:33.777 回答