使用Axios从Express应用程序返回流--“提供的值”stream“不是XMLHttpRequestResponseType类型的有效枚举值,”

tag5nh1u  于 2023-10-18  发布在  iOS
关注(0)|答案(1)|浏览(305)

我正在学习Node,Express和React,并试图将一个简单的通用Fetch方法转换为Axios,我使用该方法来调用Express API。当我希望Axios自动返回JSON数据的结果时,我已经让Axios工作了,但在这里我希望它返回ReadableStream。从文档来看,应该很简单:简单地将字段responseType:'stream'添加到config,但我一直得到错误The provided value 'stream' is not a valid enum value of type XMLHttpRequestResponseType.我看到其他人也有这个问题(见https://github.com/axios/axios/issues/1474),但我没有看到任何解决方案。有谁知道有没有,或者我做错了什么?相关代码如下。感谢任何见解!

const logic = {

 _call(path, method, headers, body, expectedStatus) {
        const config = { method,responseType:'stream', url: `http://localhost:8080/${path}`}

        if (headers) config.headers = headers
        if (body) config.data = body

        return axios( config)
            .then(res => {
                if (res.status === expectedStatus) {
                    return res
                } else
                    return res
                        .then(({ message }) => {
                            throw new Error(message)
                        })
            })
    }
}
ghhaqwfi

ghhaqwfi1#

This answer might be worth checking out if you explicitly need the stream in Axios.
也就是说,我更喜欢默认的fetch,因为它更灵活。如果有人感兴趣的话,这里有一个客户端方法,可以将流作为可迭代块的列表来获取。
从上到下,这是最终调用的样子:

const stream = await generateStream()
for await (const chunk of stream) {
  console.log(chunk)
}

generateStream函数是执行实际API调用的函数,它看起来像这样:

export const generateStream = async (): Promise<AsyncIterable<string>> => {
  const response = await fetch(
    'http://localhost:5000/api/stream/dummy?chunks_amount=50',
    {
      method: 'GET',
    }
  )
  if (response.status !== 200) throw new Error(response.status.toString())
  if (!response.body) throw new Error('Response body does not exist')
  return getIterableStream(response.body)
}

最后,这里是getIterableStream函数,它在字节块被加载时读取字节块并将其解码为字符串:

export async function* getIterableStream(
  body: ReadableStream<Uint8Array>
): AsyncIterable<string> {
  const reader = body.getReader()
  const decoder = new TextDecoder()

  while (true) {
    const { value, done } = await reader.read()
    if (done) {
      break
    }
    const decodedChunk = decoder.decode(value, { stream: true })
    yield decodedChunk
  }
}

请注意async function* getIterableStream中的星星。这个语法定义了一个asynchronous generator函数。

相关问题