Merge pull request #18888 from Snuffleupagus/MessageHandler-AbortSignal
Re-factor the `MessageHandler`-class event handler function
This commit is contained in:
commit
c88d3a31cf
@ -1982,7 +1982,7 @@ class PDFPageProxy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class LoopbackPort {
|
class LoopbackPort {
|
||||||
#listeners = new Set();
|
#listeners = new Map();
|
||||||
|
|
||||||
#deferred = Promise.resolve();
|
#deferred = Promise.resolve();
|
||||||
|
|
||||||
@ -1992,21 +1992,39 @@ class LoopbackPort {
|
|||||||
};
|
};
|
||||||
|
|
||||||
this.#deferred.then(() => {
|
this.#deferred.then(() => {
|
||||||
for (const listener of this.#listeners) {
|
for (const [listener] of this.#listeners) {
|
||||||
listener.call(this, event);
|
listener.call(this, event);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
addEventListener(name, listener) {
|
addEventListener(name, listener, options = null) {
|
||||||
this.#listeners.add(listener);
|
let rmAbort = null;
|
||||||
|
if (options?.signal instanceof AbortSignal) {
|
||||||
|
const { signal } = options;
|
||||||
|
if (signal.aborted) {
|
||||||
|
warn("LoopbackPort - cannot use an `aborted` signal.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const onAbort = () => this.removeEventListener(name, listener);
|
||||||
|
rmAbort = () => signal.removeEventListener("abort", onAbort);
|
||||||
|
|
||||||
|
signal.addEventListener("abort", onAbort);
|
||||||
|
}
|
||||||
|
this.#listeners.set(listener, rmAbort);
|
||||||
}
|
}
|
||||||
|
|
||||||
removeEventListener(name, listener) {
|
removeEventListener(name, listener) {
|
||||||
|
const rmAbort = this.#listeners.get(listener);
|
||||||
|
rmAbort?.();
|
||||||
|
|
||||||
this.#listeners.delete(listener);
|
this.#listeners.delete(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
terminate() {
|
terminate() {
|
||||||
|
for (const [, rmAbort] of this.#listeners) {
|
||||||
|
rmAbort?.();
|
||||||
|
}
|
||||||
this.#listeners.clear();
|
this.#listeners.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -69,6 +69,8 @@ function wrapReason(reason) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class MessageHandler {
|
class MessageHandler {
|
||||||
|
#messageAC = new AbortController();
|
||||||
|
|
||||||
constructor(sourceName, targetName, comObj) {
|
constructor(sourceName, targetName, comObj) {
|
||||||
this.sourceName = sourceName;
|
this.sourceName = sourceName;
|
||||||
this.targetName = targetName;
|
this.targetName = targetName;
|
||||||
@ -80,71 +82,74 @@ class MessageHandler {
|
|||||||
this.callbackCapabilities = Object.create(null);
|
this.callbackCapabilities = Object.create(null);
|
||||||
this.actionHandler = Object.create(null);
|
this.actionHandler = Object.create(null);
|
||||||
|
|
||||||
this._onComObjOnMessage = event => {
|
comObj.addEventListener("message", this.#onMessage.bind(this), {
|
||||||
const data = event.data;
|
signal: this.#messageAC.signal,
|
||||||
if (data.targetName !== this.sourceName) {
|
});
|
||||||
return;
|
}
|
||||||
}
|
|
||||||
if (data.stream) {
|
|
||||||
this.#processStreamMessage(data);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (data.callback) {
|
|
||||||
const callbackId = data.callbackId;
|
|
||||||
const capability = this.callbackCapabilities[callbackId];
|
|
||||||
if (!capability) {
|
|
||||||
throw new Error(`Cannot resolve callback ${callbackId}`);
|
|
||||||
}
|
|
||||||
delete this.callbackCapabilities[callbackId];
|
|
||||||
|
|
||||||
if (data.callback === CallbackKind.DATA) {
|
#onMessage({ data }) {
|
||||||
capability.resolve(data.data);
|
if (data.targetName !== this.sourceName) {
|
||||||
} else if (data.callback === CallbackKind.ERROR) {
|
return;
|
||||||
capability.reject(wrapReason(data.reason));
|
}
|
||||||
} else {
|
if (data.stream) {
|
||||||
throw new Error("Unexpected callback case");
|
this.#processStreamMessage(data);
|
||||||
}
|
return;
|
||||||
return;
|
}
|
||||||
|
if (data.callback) {
|
||||||
|
const callbackId = data.callbackId;
|
||||||
|
const capability = this.callbackCapabilities[callbackId];
|
||||||
|
if (!capability) {
|
||||||
|
throw new Error(`Cannot resolve callback ${callbackId}`);
|
||||||
}
|
}
|
||||||
const action = this.actionHandler[data.action];
|
delete this.callbackCapabilities[callbackId];
|
||||||
if (!action) {
|
|
||||||
throw new Error(`Unknown action from worker: ${data.action}`);
|
|
||||||
}
|
|
||||||
if (data.callbackId) {
|
|
||||||
const cbSourceName = this.sourceName;
|
|
||||||
const cbTargetName = data.sourceName;
|
|
||||||
|
|
||||||
new Promise(function (resolve) {
|
if (data.callback === CallbackKind.DATA) {
|
||||||
resolve(action(data.data));
|
capability.resolve(data.data);
|
||||||
}).then(
|
} else if (data.callback === CallbackKind.ERROR) {
|
||||||
function (result) {
|
capability.reject(wrapReason(data.reason));
|
||||||
comObj.postMessage({
|
} else {
|
||||||
sourceName: cbSourceName,
|
throw new Error("Unexpected callback case");
|
||||||
targetName: cbTargetName,
|
|
||||||
callback: CallbackKind.DATA,
|
|
||||||
callbackId: data.callbackId,
|
|
||||||
data: result,
|
|
||||||
});
|
|
||||||
},
|
|
||||||
function (reason) {
|
|
||||||
comObj.postMessage({
|
|
||||||
sourceName: cbSourceName,
|
|
||||||
targetName: cbTargetName,
|
|
||||||
callback: CallbackKind.ERROR,
|
|
||||||
callbackId: data.callbackId,
|
|
||||||
reason: wrapReason(reason),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
if (data.streamId) {
|
return;
|
||||||
this.#createStreamSink(data);
|
}
|
||||||
return;
|
const action = this.actionHandler[data.action];
|
||||||
}
|
if (!action) {
|
||||||
action(data.data);
|
throw new Error(`Unknown action from worker: ${data.action}`);
|
||||||
};
|
}
|
||||||
comObj.addEventListener("message", this._onComObjOnMessage);
|
if (data.callbackId) {
|
||||||
|
const sourceName = this.sourceName,
|
||||||
|
targetName = data.sourceName,
|
||||||
|
comObj = this.comObj;
|
||||||
|
|
||||||
|
new Promise(function (resolve) {
|
||||||
|
resolve(action(data.data));
|
||||||
|
}).then(
|
||||||
|
function (result) {
|
||||||
|
comObj.postMessage({
|
||||||
|
sourceName,
|
||||||
|
targetName,
|
||||||
|
callback: CallbackKind.DATA,
|
||||||
|
callbackId: data.callbackId,
|
||||||
|
data: result,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
function (reason) {
|
||||||
|
comObj.postMessage({
|
||||||
|
sourceName,
|
||||||
|
targetName,
|
||||||
|
callback: CallbackKind.ERROR,
|
||||||
|
callbackId: data.callbackId,
|
||||||
|
reason: wrapReason(reason),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (data.streamId) {
|
||||||
|
this.#createStreamSink(data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
action(data.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
on(actionName, handler) {
|
on(actionName, handler) {
|
||||||
@ -527,7 +532,8 @@ class MessageHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
destroy() {
|
destroy() {
|
||||||
this.comObj.removeEventListener("message", this._onComObjOnMessage);
|
this.#messageAC?.abort();
|
||||||
|
this.#messageAC = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user