Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revisionBoth sides next revision
spec:async-algos [2014/05/27 18:19] – [Making Author-Observable Changes to Page State] tabatkinsspec:async-algos [2014/05/28 12:24] – [Making Author-Observable Changes to Page State] tabatkins
Line 38: Line 38:
 Be careful about making any change to the state of the document within the asynchronous portion of the algorithm.  Any observable change must define precisely when it happens, so that observable state cannot change in the middle of author JS code; that violates JS's run-to-completion semantics.  Instead, all changes must happen in a defined task or microtask.  For example, the above algorithm is erroneous; it changes the font face's '''status''' attribute, an author-observable piece of information, without clarifying precisely when it happens. Be careful about making any change to the state of the document within the asynchronous portion of the algorithm.  Any observable change must define precisely when it happens, so that observable state cannot change in the middle of author JS code; that violates JS's run-to-completion semantics.  Instead, all changes must happen in a defined task or microtask.  For example, the above algorithm is erroneous; it changes the font face's '''status''' attribute, an author-observable piece of information, without clarifying precisely when it happens.
  
-If you do make any changes, [something about queueing a task; I'll ask Anne for more detail].+The correct way to make an observable change is in a synchronous block that is explicitly put on a task queue.  There is nice spec language for invoking this Here's the corrected version of the above code using the correct language:
  
-Note that fulfilling a promise is not author-observable; they can't tell whether it was fulfilled until the end of their code, when tasks and microtasks run, so it's safe.+> When the load() method is called, execute these steps: 
 +>  
 +> 1. Let font face be the FontFace object on which this method was called. 
 +>  
 +> 2. If font face’s %%[[Urls]] slot is null, or its status attribute is anything other than "unloaded", return font face’s [[FontStatusPromise]] and abort these steps.%% 
 +>  
 +> 3. Otherwise, set font face’s status attribute to "loading", return font face’s %%[[FontStatusPromise]], and continue executing the rest of this algorithm asynchronously.%% 
 +>  
 +> 4. Using the value of font face’s %%[[Urls]] slot, attempt to load a font as defined in [CSS3-FONTS], as if it was the value of a @font-face rule’s src descriptor.%% 
 +
 +> 5. Once the attempt to load either completes with either success or failure, await a stable state, then synchronously execute the following steps: 
 +
 +>   a. If the attempt to load failed, set font face's status attribute to "error", then reject font face's %%[[FontStatusPromise]]%% with a NetworkError. 
 +>   b. Otherwise, set font face's status attribute to "loaded", then fulfill font face's %%[[FontStatusPromise]]%% with font face. 
 + 
 +The "await a stable state" language ensures that author code has reached a point where other code can run, and that nothing else is in the queue to be run.  This ensures that, for example, the promise's callbacks will be called immediately after the status attribute is changed. 
 + 
 +If there is further asynchronous work to be done, explicitly state "Perform the rest of this algorithm asynchronously.", to avoid any possible confusion. 
 + 
 +Note that fulfilling a promise is not author-observable, because the state of a promise isn't directly exposed anywhere (and it automatically queues the promise callbacks for an upcoming microtask checkpoint).  It can be done freely in an async algorithm without the above contortions.
 
spec/async-algos.txt · Last modified: 2014/12/09 15:48 by 127.0.0.1
Recent changes RSS feed Valid XHTML 1.0 Valid CSS Driven by DokuWiki