调用Dify平台API实现工作流streaming流式返回接口封装
·
// api.ts
let currentAbortController : AbortController | null = null
let currentCencel:(() => void) | null = null
export const fetchDifyWorkflow = async (params: any, onData:(data)=>void, onError:(error:Error) => void, onComplete?: () => void): Promise<() => void> => {
// 取消之前的请求
if (currentCencel) {
currentCencel()
currentAbortController?.abort()
}
currentAbortController= new AbortController();
try {
const response = await fetch(`${difyAPIUrl}?response_mode=streaming`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${difyAPIKey}`,
'Content-Type': 'application/json',
},
body: JSON.stringify(params),
signal: currentAbortController.signal
});
if(!response.ok) {
throw new Error(`status:${response.status}`)
}
if(!response.body) {
throw new Error('readableStream not supported')
}
const reader = response.body?.getReader() // 用于获取HTTP请求体的字符流,返回BufferedReader对象
const decoder = new TextDecoder() // 将二进制数据解码为文本字符串
const buffer = ''
const processData = async ():Promise<void> => {
try {
const {down, value} = await reader?.read()
if(down) {
onCompelet?.()
return
}
buffer += decoder.decode(value, { stream: true })
const message = buffer.split('\n\n') // 根据实际情况修改
buffer = message.pop() || '' // 保留不完整信息
for (const msg of message) {
if(msg.startWith('data:')){ // 根据实际情况修改
try{
const data = JSON.parse(msg.substring(6))
onData(data)
} catch (error) {
console.log('解析error',error)
}
}
}
return processData()
} catch (err) {
// 主动取消不触发onError
if(err instanceof Error) { // TS4.4起,catch块默认unknown
if ((err as Error).name !== 'AbortError) {
onError?.(err)
}
} else {
onError?.(new Error(String(err)))
}
}
}
processData()
// 返回取消函数并保存引用
const cancel = (): void => {
reader.cancel()
currentAbortController.abort()
}
currentCencel = cancel
return currentCencel
} catch (error) {
if(err instanceof Error) { // TS4.4起,catch块默认unknown
if ((err as Error).name !== 'AbortError) {
onError?.(err)
}
} else {
onError?.(new Error(String(err)))
}
return () => {}
}
}
export const cancelRequests = (): void => {
if (currentCencel) {
currentCencel()
currentAbortController?.abort()
currentCencel = null
currentAbortController= null
}
};
更多推荐
所有评论(0)