拒绝桥交回原监听器时对齐Node的this

- unhandledRejectionBridge:交回原监听器改用 Reflect.apply 把 this 绑成 process,和 Node EventEmitter 一致,依赖 this 的原监听器不再拿到 undefined
- 补一条用例钉住 this 语义
This commit is contained in:
2026-10-02 13:06:56 +08:00
parent 3d4c42901c
commit b0f9eb2292
2 changed files with 18 additions and 2 deletions
@@ -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]);
});
@@ -27,8 +27,9 @@ function invokeRejectionListener(
reason: unknown,
promise: Promise<unknown>,
) {
// 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() {