来自节点的带有分块响应流的Axios请求

时间:2019-11-20 19:30:09

标签: node.js reactjs axios

我在React中有一个客户端应用程序,在Node(具有Express)中有一个服务器。 在服务器端,我有一个如下端点(不是真正的端点,只是我在做什么的想法):

function endpoint(req, res) {
   res.writeHead(200, {
        'Content-Type': 'text/plain',
        'Transfer-Encoding': 'chunked'
      });

   for(x < 1000){
      res.write(some_string + '\n');
      wait(a_couple_of_seconds); // just to make process slower for testing purposes
   }

   res.end();
}

这是完美的工作,我的意思是,当我调用此端点时,我收到了包含所有1.000行的整个流。

问题是我无法设法按块(对于每个“写”或一堆“写”)获取此数据,以便在我接收到它们后立即在前端显示它们。从端点调用中获取行后立即显示行的表的视图

在前端,我使用Axios通过以下代码调用API:

async function getDataFromStream(_data): Promise<any> {
    const { data, headers } = await Axios({
        url: `http://the.api.url/endpoint`,
        method: 'GET',
        responseType: 'stream',
        timeout: 0,
    });

    // this next line doesn't work. it says that 'on' is not a function
    data.on('data', chunk => console.log('chunk', chunk)); 
    // data has actually the whole response data (all the rows)

    return Promise.resolve();
}

问题是,在调用服务器上的“ res.end()”之后,Axios调用将返回整个数据对象,但是我需要在服务器开始发送带有行的块时获取数据(在每次res.write或服务器认为准备发送一些数据块时都可以使用。

我还尝试过不使用await并在axios调用的'then()'处获取promise的值,但这是相同的行为,所有'服务器执行“ res.end()”

之后,“一起写入”

那么,我在这里做错了什么?也许这对于Axios或Node是不可能的,我应该使用websockets之类的方法来解决。 任何帮助将不胜感激,因为我读了很多书,但还没有找到可行的解决方案。

1 个答案:

答案 0 :(得分:0)

对于对此感兴趣的任何人,我最终要做的是:

在客户端,我使用了Axios onDownloadProgress 处理程序,该处理程序可以处理下载的进度事件。

因此,我实现了以下内容:

function getDataFromStream(_data): Promise<any> {
    return Axios({
        url: `http://the.api.url/endpoint`,
        method: 'GET',
        onDownloadProgress: progressEvent => {
           const dataChunk = progressEvent.currentTarget.response;
           // dataChunk contains the data that have been obtained so far (the whole data so far).. 
           // So here we do whatever we want with this partial data.. 
           // In my case I'm storing that on a redux store that is used to 
           // render a table, so now, table rows are rendered as soon as 
           // they are obtained from the endpoint.
        }


    }).then(({ data }) => Promise.resolve(data));    

}