如果请求是流(Axios),如何等待所有响应块

问题描述 投票:0回答:1

我有一个代理服务器,需要向外部 API 服务器发出请求,以从某些文本合成语音。 在 API 文档中有一句话告诉我:请求后我将获得带有标头的第一个响应,之后我将获得流模式二进制数据,因为响应正文中有“传输编码:分块”。

所以,我正在使用

responseType: 'stream'
来完成这个事情和这段代码

export const synthesizeVoice = async (contentType: ContentType,
                                      dataForSynthesize: string,
                                      format: string = 'wav16', 
                                      voice:  string = 'Nec_24000') => {
    const token = await authHandler.getAuthData();
    const date  = new Date(); const timestamp = date.getTime();
    const file  = fs.createWriteStream(timestamp + '.wav'); // I'm storing getted data on server, so this one needed for that
    
    const response = await axios({
        method: 'POST',
        url: SAPI.SS_SYNTH,

        headers: {
            Authorization:  'Bearer ' + token,
            'Content-Type': (contentType === 'ssml') ? 'application/ssml' : 'application/text',
        },
        params: {
            format: format,
            voice:  voice,
        },
        data: dataForSynthesize,

        responseType: 'stream',
    });
    
    // I'm writting getted data to a file 
    response.data.pipe(file);
    // and return a path on method above in call stack to return getted binary data on front
    return file.path;
};

我的主要问题是,在获得第一个响应块后(如果我没有弄错的话),我的方法返回文件的路径(此时文件不是完整的形式),并且正面不是完整的音频文件。

我如何等待获取完整的二进制数据并仅在此之后发送它们,或者也许我应该使用来自前端的流请求来按块获取数据?

另外,也许这种方法不好,我应该使用其他方法?

UPD:工作代码

axios({
    // nothing to changes here, I've just hidden it to short code example
})
.then(resp => {
    // Event listeners on files didn't working in my case, so
    // I used it with axios response 
    resp.data.pipe(file);

    resp.data.on('end', () => {
        file.close();

        res.set({
            'Content-Type': 'audio/wav16',
        });
        const resFile = fs.createReadStream(file.path).pipe(res);
    });
})
.catch(err => {
    console.log(err.message)
});
typescript axios chunked-encoding
1个回答
0
投票

您可以尝试以这种方式消费数据。

file.on('data', chunk => {
  console.log(chunk.toString());
});

要在数据流结束后执行某些操作,可以使用

file.on('end', chunk => {
  console.log("End");
});

结合这两者,我想您将能够等待并获得完整的文件。

© www.soinside.com 2019 - 2024. All rights reserved.