浏览代码

state.js: accumulate incoming events (#1313)

If the backend yields multiple events from a single event handler, ensure that
each event gets appended to the pending result before being transferred to the
state. Previously each incoming event would overwrite any other pending
event(s) leading to racy and unpredictable behavior when yielding events from
the backend in quick succession.

Fixes #1309

Bonus Fix: when setting `processing: false` after client-side events (like
_console), spread from `result`, not `state` to avoid accumulating duplicate
queued events. I think this was originally an undiscovered bug that was exposed
by the main fix.
Masen Furer 1 年之前
父节点
当前提交
5cbf7da952
共有 1 个文件被更改,包括 4 次插入4 次删除
  1. 4 4
      reflex/.templates/web/utils/state.js

+ 4 - 4
reflex/.templates/web/utils/state.js

@@ -234,7 +234,7 @@ export const processEvent = async (
 
   // If no event was sent, set processing to false.
   if (!eventSent) {
-    setResult({ ...state, final: true, processing: false });
+    setResult({ ...result, final: true, processing: false });
   }
 };
 
@@ -281,12 +281,12 @@ export const connect = async (
   socket.current.on("event", update => {
     update = JSON5.parse(update);
     applyDelta(state, update.delta);
-    setResult({
+    setResult(result => ({
       state: state,
-      events: update.events,
+      events: [...result.events, ...update.events],
       final: update.final,
       processing: true,
-    });
+    }));
   });
 };