👑 [需求] 希望 request 能够公开例如 `onMessageHandle` `onErrorHandle` 等调控操作
nooooooom opened this issue · 1 comments
nooooooom commented
🥰 需求描述
类似 axios 的 onDownloadProgress
。
在概念上来说,现在的 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)
}
})
}
🧐 解决方案
🚑 其他信息
ONLY-yours commented
这个其实是有一定的设计的。
你如果偷瞄到 request 的 ts 提示的话就会发现,第三个参数就是 signal,相当于我们透了这个东西出来,但是我们文档上没有写,就是没想好是不是一个就够用了,感谢你的思路,我们会扩展第三个参数把这些放出来。
thanks @nooooooom