-
Notifications
You must be signed in to change notification settings - Fork 551
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
🚀 Feature Request: support for top level await? #2029
Comments
There may be more ways to avoid using a top-level await within a worker -- for example, within a request handler, you can specify pass a promise to There's an open issue with the bundler we use internally to support top-level await, and from skimming quickly it looks like while it would be technically possible for us to support TLA, the actual implementation is not ideal. I'll keep this issue open for now as a way of tracking evanw/esbuild#253, so that once support is added in esbuild we can enable it within wrangler -- but given that the last update was about a year ago, I don't anticipate this being added any time soon. |
I believe this error is misleading as the target environment mentioned in it refers to the esbuild config that is controlled internally in Wrangler and not configurable by the user. I filed #2716 to update the target version. This doesn't make the top level await magically work, but it is possible to work because the workerd runtime doesn't support top-level awaits outside of a request context. There is however a workaround here, break up your worker and dynamically import a module with top level awaits from within a
export default {
async fetch(request, environment, context) {
const myWorker = (await import('./my-worker')).default;
return myWorker.fetch(request, environment, context);
}
await Promise.resolve('yay, it works!');
export default {
async fetch(request, environment, context) {
...
}
} This works (assuming patch for #2716) because the top level await is in an ES module that is dynamically imported from within a fetch handler. Without the dynamic import, you'll get:
|
hmm... the approach I proposed above might trigger "The script will never generate a response." error described in cloudflare/workerd#210 if the runtime is hit by two requests while awaiting the initialization. |
I tried various things (especially using context.waitUntil) to make the top level await work, but nothing worked reliably, so I ended up resorting to the only thing that does seem to work reliably:
export default {
async fetch(request, environment, context) {
const myWorker = (await import('./my-worker')).default;
return myWorker.fetch(request, environment, context);
}
const workerInit = Promise.resolve('yay, it works!');
export default {
async fetch(request, environment, context) {
await workerInit;
...
}
} |
I believe that this is now resolved with fix for #2716, there is still an issue related to cloudflare/workerd#389 and cloudflare/workerd#402 but those should be tracked separately. |
to clarify, I verified that top-level |
Describe the solution
Some libraries already use top level
await
. And I think you should allow this too. I dont see any problems with this, and if there is any, can be easily bypassed with an async function, but it harms code readability (dont want my whole file's code to go inside an async function). So can we please consider this?The text was updated successfully, but these errors were encountered: