diff --git a/README.md b/README.md index 6d4359a..3ed70a7 100644 --- a/README.md +++ b/README.md @@ -274,7 +274,9 @@ Currently (in a world without top-level `await`), polyfills are synchronous. So, Yes. In particular, if none of the imported modules have a top-level `await`, there will still be a delay of some turns on the Promise job queue until the module body executes. The goal here is to avoid too much synchronous behavior, which would break if something turns out to be asynchronous in the future, or even alternate between those two depending on runtime conditions ("releasing Zalgo"). Similar considerations led to the decision that `await` should always be asynchronous, even if passed a non-Promise. -Note, this is an observable change from current ES Module semantics, where the Evaluate phase is entirely synchronous. For a concrete example and further discussion, see [issue #43](https://github.com/tc39/proposal-top-level-await/issues/43) +To avoid reordering the execution of modules due to job queue activity, when there is no need to wait on a not-yet-resolved module, the job queue is run to completion after loading a module. + +Note, this is an observable change from current ES Module semantics, where the Evaluate phase is entirely synchronous. For a concrete example and further discussion, see [issue #43](https://github.com/tc39/proposal-top-level-await/issues/43) and [#47](https://github.com/tc39/proposal-top-level-await/issues/47). #### Does top-level `await` increase the risk of deadlocks? diff --git a/spec.html b/spec.html index 4ff7ffe..fcb04d4 100644 --- a/spec.html +++ b/spec.html @@ -370,11 +370,9 @@

InnerModuleEvaluation( _module_, _stack_, _index_ )

1. If _requiredModule_.[[Status]] is `"evaluating"`, then 1. Assert: _requiredModule_ is a Source Text Module Record. 1. Set _module_.[[DFSAncestorIndex]] to min(_module_.[[DFSAncestorIndex]], _requiredModule_.[[DFSAncestorIndex]]). - 1. Let _stackErrorCapability_ be ! NewPromiseCapability(%Promise%). - 1. Perform ! PerformPromiseThen(_requiredModule_.[[ExecPromise]], *undefined*, _stackErrorCapability_.[[Reject]]). - 1. Add _stackErrorCapability_ to the list _dependencyExecPromises_. 1. Perform ? ModuleExecution(_module_). 1. Perform ! ExecuteModuleWhenImportsReady(_module_, _dependencyExecPromises_, _evalCapability_). + 1. Perform ! FlushJobs(). 1. Assert: _module_ occurs exactly once in _stack_. 1. Assert: _module_.[[DFSAncestorIndex]] is less than or equal to _module_.[[DFSIndex]]. 1. If _module_.[[DFSAncestorIndex]] equals _module_.[[DFSIndex]], then @@ -384,6 +382,7 @@

InnerModuleEvaluation( _module_, _stack_, _index_ )

1. Remove the last element of _stack_. 1. Set _requiredModule_.[[Status]] to `"evaluated"`. 1. If _requiredModule_ and _module_ are the same Module Record, set _done_ to *true*. + 1. Otherwise, set _requiredModule_.[[ExecPromise]] to _module_.[[ExecPromise]]. 1. Return _index_. @@ -508,6 +507,20 @@

Runtime Semantics: TopLevelModuleEvaluationJob ( _sourceText_, _hostDefined_

An implementation may parse a _sourceText_ as a |Module|, analyse it for Early Error conditions, and instantiate it prior to the execution of the TopLevelModuleEvaluationJob for that _sourceText_. An implementation may also resolve, pre-parse and pre-analyse, and pre-instantiate module dependencies of _sourceText_. However, the reporting of any errors detected by these actions must be deferred until the TopLevelModuleEvaluationJob is actually executed.

+ + +

FlushJobs ( )

+ + 1. Assert: There is no running execution context. + 1. Yield control to the RunJobs algorithm. + 1. When RunJobs has no more jobs to run, return from this algorithm. + + +

This algorithm completes asynchronously, but is to be used synchronously within a larger ECMAScript algorithm. For this reason, it may only be called when there is no running execution context.

+

HTML and ECMAScript have different notions of how the Job Queue works, with HTML employing a willful violation to describe the layering; see Integration with the JavaScript job queue for details.See #735 for one approach to improving the layering. Until some kind of fix in this area occurs, this proposal sticks with the "willful violation" layering approach.

+

In the HTML context, the FlushJobs() algorithm would be replaced, via a willful violation, with the perform a microtask checkpoint algorithm

+
+