@@ -277,6 +277,59 @@ describe('竞态场景:IntersectionObserver 与子组件 created 的时序', (
277277 expect ( elapsed ) . toBeLessThan ( 50 )
278278 expect ( observerCallbackLog [ 0 ] . listenerRegisteredBeforeEmit ) . toBe ( true )
279279 } )
280+
281+ it ( '【关键】二次打开场景:addIntersectionObserver 到达时 pendingSetupCount 已为 0,但 DOM 出现后 setup 才开始' , async ( ) => {
282+ /**
283+ * 模拟二次打开的精确时序:
284+ * - 关闭弹框时 sliding-scale 销毁,_pendingSetupCount 早已归零
285+ * - 重新打开:addIntersectionObserver 的 invokeAPI 消息先到达 render 侧(同步分发)
286+ * - show 的 setData 经 queueMicrotask + $nextTick 后才触发 Vue re-render
287+ * - 所以 addIntersectionObserver 到达时,sliding-scale 的 setup 甚至还没开始
288+ * - _pendingSetupCount 此刻为 0,不能直接 resolve
289+ *
290+ * 正确做法:先等 DOM 出现(waitForElement),DOM 出现时 setup 已发 mC(count++),
291+ * 然后再 waitForPendingSetups,等 created 完成后才建立 observer
292+ */
293+
294+ // 模拟"先等 DOM 出现(期间 setup 开始),再等 pending setups"的正确顺序
295+ let domAppeared = false
296+ let setupStarted = false
297+
298+ // step1: addIntersectionObserver 到达,此时 count=0(弹框已关再开)
299+ expect ( tracker . _pendingSetupCount ) . toBe ( 0 )
300+
301+ // step2: 模拟 waitForElement 异步等待 DOM(此时 setup 还没开始)
302+ const domReadyPromise = new Promise ( ( resolve ) => {
303+ setTimeout ( ( ) => {
304+ // DOM 出现:同时触发 setup 开始(beginSetup)
305+ setupStarted = true
306+ tracker . beginSetup ( )
307+ domAppeared = true
308+ resolve ( )
309+ } , 5 )
310+ } )
311+
312+ // step3: 等 DOM 出现
313+ await domReadyPromise
314+ expect ( domAppeared ) . toBe ( true )
315+ expect ( setupStarted ) . toBe ( true )
316+ expect ( tracker . _pendingSetupCount ) . toBe ( 1 ) // DOM 出现后 count 变为 1
317+
318+ // step4: 现在 waitForPendingSetups,等 created 完成
319+ const waitPromise = tracker . waitForPendingSetups ( )
320+
321+ // step5: 模拟 service 侧 created 完成(注册 EventBus),然后 completeSetup
322+ await new Promise ( resolve => setTimeout ( resolve , 5 ) )
323+ eventBus . once ( 'needFeedBack' , ( ) => { } )
324+ tracker . completeSetup ( )
325+
326+ await waitPromise
327+
328+ // step6: 此时建立 observer 并触发(EventBus 监听已注册)
329+ const listenerRegistered = eventBus . has ( 'needFeedBack' )
330+ expect ( listenerRegistered ) . toBe ( true )
331+ eventBus . emit ( 'needFeedBack' )
332+ } )
280333} )
281334
282335describe ( '边界情况' , ( ) => {
0 commit comments