Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Top-level awaits should be awaited before executing the next userscript #2334

Open
cow1337killer3 opened this issue Jan 15, 2025 · 1 comment

Comments

@cow1337killer3
Copy link

cow1337killer3 commented Jan 15, 2025

(Please fill out the issue template with your details)

Expected Behavior

Let's say we have userscript1 (pos # 1) and userscript2 (pos # 2).

If neither have a top-level await, userscript1 will execute from start to finish, and then userscript2 will execute from start to finish.

If userscript1 has a top-level await (in Chrome it needs to be put on the event loop and not executed directly, like a fetch), you'd expect the code afterwards to finish executing before userscript2 starts executing.

Actual Behavior

userscript2 in most cases will start executing before the remaining code of userscript1 that is after the top-level await.

If the execution order of userscripts isn't guaranteed, then what's the point of specifying the position setting of each?

Specifications

  • Chromium: 131.0.6778.265
  • TM: 5.3.3
  • OS: Windows 11 Home 23H2

Script

// ==UserScript==
// @name userscript1
// @match *://*/*
// ==/UserScript==
console.log('1 start')
await fetch('.')
console.log('1 end')
// ==UserScript==
// @name userscript2
// @match *://*/*
// ==/UserScript==
console.log('2 start')

Output:

1 start
2 start
1 end

I think a possible solution could be to just wrap each userscript in an async function and await a call to it.

@7nik
Copy link

7nik commented Jan 15, 2025

Top-level await works only in script modules where dependency on other scripts (modules) is clearly defined.
Userscripts don't have such dependency definition, and it will cause trouble for people with hundreds of scripts per page.

If you need to await another script, use markers and events:

// userscript1
await something;
window.dispatchEvent(new CustomEvent("script-finished", { detail: { foo, bar } }));
document.documentElement.classList.add("script1-finished");

// userscript2
if (document.documentElement.classList.contains("script1-finished")) {
  // userscript1 already finished
} else {
  window.addEventListener("script-finished", (ev) => {
    const { foo, bar } = ev.detail;
    // do something
  });
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants