ant-design/pro-chat

👑 [需求] 希望 request 能够公开例如 `onMessageHandle` `onErrorHandle` 等调控操作

nooooooom opened this issue · 1 comments

🥰 需求描述

类似 axiosonDownloadProgress

在概念上来说,现在的 request 的设计为需要将不同种类的 response 转换为一个通用的 Response<ReadableStream | string>,以此来保证流式数据的读取,对于 因此 Request 我们设计为返回有且只是一个 String 这段文档描述来说可能有些不同。

在使用上来说,不管是非流式的请求,还是在应用中比较常见的基于 axios 的请求,都需要对返回结果再进行一层的封装才能够让 ProChat 进行使用(基于 axios 的流式数据还需要手动管理 ReadableStream 的报错、关闭等状态),接入进来比较麻烦,也容易污染原有的代码。

这是基于 axios 的代码:

request(messages, options) {
  return new Promise((resolve, reject) => {
    // axios 只会在请求完成之后进行数据返回,因此需要自己维护一个 ReadableStream
    const stream = new ReadableStream({
      start(controller) {
        const encoder = new TextEncoder()
        let isClosed = false
        axios
          .post(url, data, {
              signal: options.signal,
              onDownloadProgress: (event) => {
                const { responseText } = event.target
                controller.enqueue(encoder.encode(responseText))
               }
             }
           }
         )
         .catch((error) => {
           reject(error)
           controller.error(error)
           isClosed = true
         })
         .finally(() => {
           if (!isClosed) {
             controller.close()
             isClosed = true
           }
         })
     }
   })
   resolve(new Response(stream))
  })
}

但是其实对于流式的数据来说,只要数据流没有完成那么 request 的 Promise 状态也应该还是 Pending,ChatItem 展示的是另一种形式的 Progress,最终的 message 并没有真正的加载下来。希望 request 能够公开例如 onMessageHandle onErrorHandle 等调控操作,将流式作为是一种过渡状态而不是最终数据的缩影。

公开之后的代码:

request(messages, options) {
    return axios.post(url, data, {
      signal: options.signal,
      onDownloadProgress: (event) => {
        const { responseText } = event.target
        // 仅仅是将流式的处理逻辑替换为 `options.onMessageHandle`
        options.onMessageHandle(responseText)
      }
    })
  }

🧐 解决方案

🚑 其他信息

这个其实是有一定的设计的。

你如果偷瞄到 request 的 ts 提示的话就会发现,第三个参数就是 signal,相当于我们透了这个东西出来,但是我们文档上没有写,就是没想好是不是一个就够用了,感谢你的思路,我们会扩展第三个参数把这些放出来。

thanks @nooooooom