-
Notifications
You must be signed in to change notification settings - Fork 24
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
Provide some terms to block in parallel steps. #36
Comments
Is the issue here that you don't think the phrase "wait until p settles" has a precise enough definition? What definition would you suggest? Since this isn't something that can be accomplished in JavaScript itself, I'm not sure how to define it. |
I don't know if it's precise enough. If it is, then just an example might suffice. I'd probably crib the definition from https://html.spec.whatwg.org/multipage/webappapis.html#await-a-stable-state:
Then there should be an example of using "If promise p is fulfilled with value v" to bind v to the value of p's [[PromiseResult]] internal slot, and an example of using "If promise p is rejected with reason r" to bind r to the value of p's [[PromiseResult]] internal slot. http://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects defines the "is fulfilled" and "is rejected" terms. It would probably also be useful to define "the value of p" and "the rejection reason of p" for use in "Otherwise" clauses that don't explicitly test "is fulfilled/rejected". On the other hand, it might be better to do something other than the straightforward approach above. I'm finding that a lot of algorithms want to propagate rejection from any promise in their "in parallel" section to the promise they return, and it's easy to forget to write "If subPromise is rejected with reason r, reject mainPromise with r and abort these steps." I might like to write:
except then it won't be clear which substeps to abort on failure. Instead, how about:
Then we'd define propagating exceptions to a promise p as surrounding its sub-steps with:
And awaiting similar to ES7:
It would be nicer to let people write "Await(p)" like EcmaScript does, rather than "the result of awaiting p" like most Web standards do, but that's a separable argument. |
Ah this is helpful, yeah.
Do you think those terms are ambiguous as-is?
This is best handled with fulfillment transformations. Then you get rejection propagation for free.
I think you were probably trying to just give an example usage, but this kind of thing is exactly what we're trying to avoid. That would be better written as
As such I am hesitant of handing out foot-guns if it's going to encourage this kind of code. In general you should almost never create a promise, wait for another promise, then resolve the original promise. If that is the envisioned use case for "awaiting" or "blocking" then we should not have any term for it. |
[Sorry for the essay here. I don't know the right answer, so I'm mentioning partial solutions and their problems.]
I haven't thought of another plausible meaning, but in writing a spec I'm hesitant to use undefined terms.
"Transforming p with a fulfillment handler" results in an extra level of indentation for each promise awaited in the algorithm, as https://slightlyoff.github.io/ServiceWorker/spec/service_worker/index.html#cache-addAll-method shows. Jungkees could also have written that as:
But this has the downside of widely separating the name of the intermediate variable ("Let X be the result of transforming...") from its initialization ("Return the result of...").
Yes, it was just a usage example for more complex cases where the obvious optimizations fail.
We already have the "Upon fulfillment" footgun, which encourages actually-incorrect specs (see every use in Service Worker as of 2015-02-12). Await would at worst encourage stylistically bad specs. But maybe we can make it better. The pattern of "continue running these steps" or "run the remaining steps" is widely used in HTML, so maybe:
Unfortunately, we still have an asymmetry between the first promise and subsequent ones:
The "Resolve p" vs "Return" inconsistency prevents defining "Transform promise" to return, since returning isn't always right. If we can resolve that, "Return the result of transforming X using the remaining steps as its fulfilment handler, binding its value to Y" is still quite verbose. "Await X as Y" could just be shorthand for that. (Once we're inside a fulfillment handler anyway, we don't need the explicit "propagating exceptions to P", since For reference, my first use of "wait for X to settle" is at https://webbluetoothcg.github.io/web-bluetooth/#dfn-create-a-bluetoothgattcharacteristic-representing, and Service Workers use it in several places, some of which could be optimized. At least one of Service Worker's uses is also incorrect, but that would be more clear with documentation in the promises-guide that we can only use "wait to settle" inside an "in parallel" block. |
+1 for @jyasskin's hope for a better shorthand. I know that @domenic wants the guide to help produce coherent specs that make sense to both spec authors and implementers. We're both a bit burned by the way WebIDL hurt understandability by removing flexibility, so working back towards providing good shorthands requires overcoming some learned aversion. |
The terms in this guide are currently all aimed at execution in steps that block the main event loop, so they transform promises instead of waiting on them. However, lots of steps run in parallel, where blocking is acceptable. In those contexts, it would be nice to be able to simply wait for a promise to settle and then respond to the result. For some examples of this, search for "settles" in http://www.w3.org/TR/service-workers/.
The text was updated successfully, but these errors were encountered: