fix(runtime): fix recursive dispatches of unload event (#9207)

This commit is contained in:
Yoshiya Hinosawa 2021-01-21 16:44:48 +09:00 committed by GitHub
parent 8bef29fd74
commit 18ac7d40c8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 21 additions and 3 deletions

View file

@ -1,4 +1,9 @@
window.onunload = () => { window.onunload = () => {
console.log("onunload is called"); console.log("onunload is called");
// This second exit call doesn't trigger unload event,
// and therefore actually stops the process.
Deno.exit(1);
console.log("This doesn't show up in console");
}; };
// This exit call triggers the above unload event handler.
Deno.exit(0); Deno.exit(0);

View file

@ -2665,6 +2665,7 @@ itest!(_077_fetch_empty {
itest!(_078_unload_on_exit { itest!(_078_unload_on_exit {
args: "run 078_unload_on_exit.ts", args: "run 078_unload_on_exit.ts",
output: "078_unload_on_exit.ts.out", output: "078_unload_on_exit.ts.out",
exit_code: 1,
}); });
itest!(_079_location_authentication { itest!(_079_location_authentication {

View file

@ -24,9 +24,12 @@
} }
function exit(code = 0) { function exit(code = 0) {
// Invokes the `unload` hooks before exiting // Dispatches `unload` only when it's not dispatched yet.
// ref: https://github.com/denoland/deno/issues/3603 if (!window[Symbol.for("isUnloadDispatched")]) {
window.dispatchEvent(new Event("unload")); // Invokes the `unload` hooks before exiting
// ref: https://github.com/denoland/deno/issues/3603
window.dispatchEvent(new Event("unload"));
}
core.jsonOpSync("op_exit", { code }); core.jsonOpSync("op_exit", { code });
throw new Error("Code not reachable"); throw new Error("Code not reachable");
} }

View file

@ -305,6 +305,15 @@ delete Object.prototype.__proto__;
defineEventHandler(window, "load", null); defineEventHandler(window, "load", null);
defineEventHandler(window, "unload", null); defineEventHandler(window, "unload", null);
const isUnloadDispatched = Symbol.for("isUnloadDispatched");
// Stores the flag for checking whether unload is dispatched or not.
// This prevents the recursive dispatches of unload events.
// See https://github.com/denoland/deno/issues/9201.
window[isUnloadDispatched] = false;
window.addEventListener("unload", () => {
window[isUnloadDispatched] = true;
});
runtimeStart(runtimeOptions); runtimeStart(runtimeOptions);
const { const {
args, args,