From b0f9eb2292b6888b20758ed6a5b395f4b1c530db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=BE=B7=E5=AE=87?= Date: Fri, 2 Oct 2026 13:06:56 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8B=92=E7=BB=9D=E6=A1=A5=E4=BA=A4=E5=9B=9E?= =?UTF-8?q?=E5=8E=9F=E7=9B=91=E5=90=AC=E5=99=A8=E6=97=B6=E5=AF=B9=E9=BD=90?= =?UTF-8?q?Node=E7=9A=84this?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - unhandledRejectionBridge:交回原监听器改用 Reflect.apply 把 this 绑成 process,和 Node EventEmitter 一致,依赖 this 的原监听器不再拿到 undefined - 补一条用例钉住 this 语义 --- .../tests/unhandledRejectionBridge.test.ts | 15 +++++++++++++++ .../tests/unhandledRejectionBridge.ts | 5 +++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/apps/ai-game-creator-shell/tests/unhandledRejectionBridge.test.ts b/apps/ai-game-creator-shell/tests/unhandledRejectionBridge.test.ts index 3022d8f4e..9b796227d 100644 --- a/apps/ai-game-creator-shell/tests/unhandledRejectionBridge.test.ts +++ b/apps/ai-game-creator-shell/tests/unhandledRejectionBridge.test.ts @@ -71,3 +71,18 @@ test('window 侧读过 reason 的拒绝不再交回原监听器', () => { expect(consumed).toEqual([reason]); expect(forwarded).toEqual([]); }); + +test('交回原监听器时 this 绑成 process,和 Node EventEmitter 一致', () => { + parkProcessListeners(); + const receivers: unknown[] = []; + const listener = function (this: unknown) { + receivers.push(this); + }; + processListeners.push(listener); + process.on('unhandledRejection', listener); + installed.push(installUnhandledRejectionBridge()); + + process.emit('unhandledRejection', new Error('需要交回'), Promise.resolve()); + + expect(receivers).toEqual([process]); +}); diff --git a/apps/ai-game-creator-shell/tests/unhandledRejectionBridge.ts b/apps/ai-game-creator-shell/tests/unhandledRejectionBridge.ts index c61cabea4..7e5a5aac6 100644 --- a/apps/ai-game-creator-shell/tests/unhandledRejectionBridge.ts +++ b/apps/ai-game-creator-shell/tests/unhandledRejectionBridge.ts @@ -27,8 +27,9 @@ function invokeRejectionListener( reason: unknown, promise: Promise, ) { - // once 包装必须调它包裹的原函数:脱离 emitter 直接调用包装会碰到 this 为空。 - (listener.listener ?? listener)(reason, promise); + // once 包装必须调它包裹的原函数;Node 的 EventEmitter 把 this 绑成 process, + // 这里用 Reflect.apply 对齐,别让依赖 this 的原监听器拿到 undefined。 + Reflect.apply(listener.listener ?? listener, process, [reason, promise]); } export function installUnhandledRejectionBridge() {