You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中使用Stream Reader读取服务器流式响应时阻塞,需等流关闭才接收全部数据的问题求助

React中使用Stream Reader读取服务器流式响应时阻塞,需等流关闭才接收全部数据的问题求助

我现在遇到一个棘手的问题:想实现用户点击按钮后,把数据POST到后端,同时持续从后端流式获取数据,并在每收到一块数据时实时更新前端(目前先做console.log测试)。我用了JavaScript的Stream Reader来处理这个任务,但实际效果和预期完全不符。

预期的行为是每收到一块数据就立刻console.log出来,但实际情况却是Reader一直等到整个流关闭后,才一次性输出所有内容。我看了很多相关示例,都是收到一块数据就继续读取下一块,实在搞不懂哪里出问题了。

下面是相关代码,页面上有上传按钮和确认按钮,点击确认按钮会提交之前上传的数据:

const UploadActions = (props: UploadActionsProps) => {
    const [isDialogOpen, setIsDialogOpen] = useState<boolean>(false);
    const [loadSwitch, setLoadSwitch] = useState<boolean>(false);
    const {authToken} = useContext(AuthTokenContext);
    const {
        isObjectUploaded, setIsObjectUploaded,
        uploadObjects, setUploadObjects,
        uploadObjectErr, setUploadObjectErr
    } = useContext(UploadObjectContext) as DataTransferObjectContextType;

    useEffect(() => {
        (async () => {
            // uploadObjects contain data uploaded in a previous page
            if (!isObjectUploaded || uploadObjects.length === 0 || !loadSwitch){
                return
            }

            const url = `/add/data`;

            const response = await fetch(url, {
                method: 'POST',
                headers: {
                    'Content-Type': 'text/event-stream',
                    "authenticity-token": authToken
                },
                body: JSON.stringify(uploadObjects)
            });

            // Check if the response is a readable stream
            if (response.body) {
                const reader = response.body.getReader();
                const decoder = new TextDecoder();
                let done = false;
                // Read the stream in chunks and process them
                while (!done) {
                    const { value, done: doneReading } = await reader.read(); // this is where the problem is. The while loop does not continue until done is set
                    done = doneReading;

                    // Decode the chunk into text
                    const chunk = decoder.decode(value, { stream: true });
                    console.log(chunk)
                }

                console.log("done reading values")
            } else {
                console.error('Stream is not available');
            }
        })();
    }, [loadSwitch]);


    const handleUploadActions = (confirmation: boolean): void => {
        if (confirmation) {
            setLoadSwitch(true)
        }
        setIsDialogOpen(!isDialogOpen);
    }
   
    return (
                    {/* submit button. When this is pressed confirmation appears */}  
                    <Button
                        onClick={() => {setIsDialogOpen(true); setLoadSwitch(false)}}
                        sx={styles.saveButton}
                    >
                        <Typography sx={styles.buttonText}>Save Data</Typography>
                    </Button>
            {/* confirmation button. When clicked handleUploadActions function gets triggered */}
            {isDialogOpen &&
                <ConfirmationDialog
                    handleAction={handleUploadActions}
                    submitLabel={"Yes I'm sure"}
                    dialogTitle={"Are you sure you want to save?"}
                >
                </ConfirmationDialog>
            }
    );
};

export default UploadActions;

我怀疑是不是React的状态处理有问题,但实在想不通这会怎么影响Stream Reader的行为,有没有大佬能帮我看看?

备注:内容来源于stack exchange,提问作者PPGoodMan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.15 03:20:15