Supporting JS Promise
and await
with the QuickJS Job system
#4331
Unanswered
eddyashton
asked this question in
Ideas
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
Our JS interpreter doesn't currently run any queued jobs - it expects a single synchronous function call. This means we can't implement any standard APIs that use
Promise
s (eg - web crypto).I think it should be pretty easy to support these. The true execution will remain a synchronous block, as it currently is, but we can pump all of the async work that the application code has give us.
For instance, when executing the following handler:
We'll currently print
And completely ignore the queued jobs that would print B and C. Executing those is simple; after calling
JS_Call
to execute the main function, we should callJS_ExecutePendingJob
until it returns 0 or an error, to execute all of the pending work. See for instance the same pattern in the qjs CLI interpreter - evaluate a file, then flush any pending jobs.This doesn't really help - all of the jobs added in this way are merely queued, and it seems equally valid to execute them never, as to execute them linearly just before responding. The more interesting case is when we want to
await
any of thesePromise
s, or aPromise
from a standard API. This involves turning the request handler (or validation function, or whatever we're evaluating) into an async function:We need an
async
decorator on the function signature to callawait
within it, and the result is that the first call toJS_Call
returns aPromise
rather than a useful result. It appears the only way to recognise this is to call the function, and duck-type test if the result is aPromise
(see here - no public indication the function is async, or the response is an auto-Promise
, no way to distinguish from returning a 'real'Promise
). But that's still something we could do, and if we detect the result is aPromise
, we continue toJS_Call
it until its not (potentially pumping the pending jobs each time? Not sure if that's necessary).This is roughly equivalent to saying that your top-level handler is called as
result = await fn(request);
rather thanresult = fn(request);
.Beta Was this translation helpful? Give feedback.
All reactions