Re: [heycam/webidl] Import the Promises Guide. (#772)

domenic commented on this pull request.

Yaaaay!

This is missing "transforming", used by at least service worker and streams.

> @@ -8041,38 +8043,32 @@ ECMAScript Object values.
 
 <h4 id="es-promise">Promise types — Promise&lt;|T|&gt;</h4>
 
-IDL [=promise type=] values are
-represented by ECMAScript {{ECMAScript/Promise}}
-objects.
+IDL [=promise type=] values are represented by ECMAScript {{ECMAScript/PromiseCapability}} records.

Nit: This is not an interface, so shouldn't be using IDL syntax or be tagged as such in the Bikeshed metadata.

>  
-    1.  Let |promise| be the promise object of type <a interface lt="Promise">Promise&lt;|T|&gt;</a>.
-    1.  Let |onFulfilled| be a new [=built-in function object=] whose
-        behavior when invoked is as follows:
+    1.  Let |onFulfilledSteps| be the following steps:

I think "given an argument |V|" would be fine here and remove some of the future boilerplate. (Same for onRejected.)

> @@ -8083,21 +8079,395 @@ objects.
                 return <emu-val>undefined</emu-val>.
             1.  Otherwise, return the result of performing any steps that were required to be run if the promise was fulfilled,
                 with |value| as the promise’s value.

maybe "given |value|" (same below)

>      IDL [=promise type=] represents.
 </p>
 
 <div algorithm>
 
-    One can <dfn id="dfn-perform-steps-once-promise-is-settled" export lt="upon settling">perform some steps once a promise is settled</dfn>.
-    There can be one or two sets of steps to perform,
-    covering when the promise is fulfilled, rejected, or both.
-    When a specification says to perform some steps once a promise is settled,
-    the following steps must be followed:
+    To <dfn id="dfn-perform-steps-once-promise-is-settled" export lt="upon settling">perform some steps once a promise is settled</dfn>,
+    given a <a interface lt="Promise">Promise&lt;|T|&gt;</a> |promise| and one or two sets of steps to perform,

Add `<code>` too :). Here and below.

>  </div>
 
-<p class="issue">
-    Include an example of how to write spec text using this term.
-</p>
+<div algorithm>
+    To <dfn export for=Promise lt="a new promise">create</dfn> a new

Thank you for the "a new promise" linking text

>  </div>
 
-<p class="issue">
-    Include an example of how to write spec text using this term.
-</p>
+<div algorithm>
+    To <dfn export for=Promise lt="a new promise">create</dfn> a new
+    <a interface lt="Promise">Promise&lt;<var ignore>T</var>&gt;</a> in a [=Realm=] |realm|,
+    perform the following steps:
+
+    1.  Let |constructor| be |realm|.\[[Intrinsics]].[[{{%Promise%}}]].
+    1.  Return [=?=] [$NewPromiseCapability$](|constructor|).
+</div>
+
+<div algorithm>
+    To create a <dfn export for=Promise>resolved promise</dfn> of type

"create a promise resolved with" or "a promise resolved with" is the common usage; it would be good to have those either as the main dfn text or as alternate linking text.

> +            1.  If |fullfilledCount| equals |total|, then perform |successSteps| given |result|.
+        1.  Let |fulfillmentHandler| be [=!=] [$CreateBuiltinFunction$](|fulfillmentHandler|, « »):
+        1.  Perform [$PerformPromiseThen$](|promise|, |fulfillmentHandler|, |rejectionHandler|).
+        1.  Set |index| to |index| + 1.
+</div>
+
+This phrase is useful when you wish to aggregate the result of multiple promises, and react to them
+all together, in the same way that {{Promise/all()|Promise.all()}} functions for JavaScript code.
+
+<div algorithm>
+    To
+    <dfn id="waiting-for-all-promise" export lt="get a promise to wait for all|getting a promise to wait for all">get a promise for waiting for all</dfn>
+    with a [=list=] of <a interface lt="Promise">Promise&lt;|T|&gt;</a> values |promises| and a
+    [=Realm=] |realm|, perform the following steps:
+
+    1.  Let |promise| be [=Promise/a new promise=] of type Promise&lt;sequence&lt;|T|>> in |realm|.

`Promise&lt;sequence&lt;|T|>>` needs `<code>`, and probably ideally some links.

> +    <pre highlight="webidl">
+        interface I {
+          Promise&lt;void> delay(unrestricted double ms);
+        };
+    </pre>
+
+<div algorithm="delay">
+
+    The <code>delay(|ms|)</code> method steps are:
+
+    1.  Let |realm| be <b>this</b>'s [=relevant Realm=].
+    1.  If |ms| is NaN, let |ms| be +0; otherwise let |ms| be the maximum of |ms| and +0.
+    1.  Let |p| be [=Promise/a new promise=] in |realm|.
+    1.  Run the following steps [=in parallel=]:
+        1.  Wait |ms| milliseconds.
+        1.  [=Promise/Resolve=] |p| with the {{void}} value.

It'd be nice if we could make the argument optional for cases like this; WDYT?

> +    The <code>delay(|ms|)</code> method steps are:
+
+    1.  Let |realm| be <b>this</b>'s [=relevant Realm=].
+    1.  If |ms| is NaN, let |ms| be +0; otherwise let |ms| be the maximum of |ms| and +0.
+    1.  Let |p| be [=Promise/a new promise=] in |realm|.
+    1.  Run the following steps [=in parallel=]:
+        1.  Wait |ms| milliseconds.
+        1.  [=Promise/Resolve=] |p| with the {{void}} value.
+    1.  Return |p|.
+</div>
+
+The equivalent function in JavaScript would be
+
+<pre highlight="js">
+function delay(ms) {
+    // Verify the this value is correct.

```suggestion
    // Omitted: verify the this value is correct.
```

and the same below.

Although, I am unsure if we really need to preserve these JavaScript versions, given the Web IDL spec audience. They are somewhat problematic, depending on how strongly you take "equivalent".

> +    If any of the fetches fail, it will return [=Promise/rejected promise|a promise rejected with=]
+    that failure.
+
+    <pre highlight="webidl">
+        interface I {
+          Promise&lt;sequence&lt;Response>> batchRequest(sequence&lt;USVString> urls);
+        };
+    </pre>
+
+<div algorithm="batchRequest">
+
+    The <code>batchRequest(|urls|)</code> method steps are:
+
+    1.  Let |responsePromises| be « ».
+    1.  [=list/For each=] |url| of |urls|:
+        1.  Let |p| be the result of calling {{WindowOrWorkerGlobalScope/fetch()}} with |url|.

Maybe better "running the steps specified by the fetch() method"

> +
+    <pre highlight="webidl">
+        interface I {
+          Promise&lt;sequence&lt;Response>> batchRequest(sequence&lt;USVString> urls);
+        };
+    </pre>
+
+<div algorithm="batchRequest">
+
+    The <code>batchRequest(|urls|)</code> method steps are:
+
+    1.  Let |responsePromises| be « ».
+    1.  [=list/For each=] |url| of |urls|:
+        1.  Let |p| be the result of calling {{WindowOrWorkerGlobalScope/fetch()}} with |url|.
+        1.  [=list/Append=] |p| to |responsePromises|.
+    1.  Let |p| be [=getting a promise to wait for all=] with |responsePromises|.

```suggestion
    1.  Let |p| be the result of [=getting a promise to wait for all=] with |responsePromises|.
```

>  </div>
 
 <p id="promise-to-es">
     The result of [=converted to an ECMAScript value|converting=]
     an IDL [=promise type=] value to an ECMAScript
-    value is the {{ECMAScript/Promise}} value that represents a reference to the same object that the
+    value is the value of the \[[Promise]] field of the record that
     IDL [=promise type=] represents.
 </p>
 
 <div algorithm>

Maybe introduce a subheading here, something like "Creating and manipulating promises"?

>      IDL [=promise type=] represents.
 </p>
 
 <div algorithm>
 
-    One can <dfn id="dfn-perform-steps-once-promise-is-settled" export lt="upon settling">perform some steps once a promise is settled</dfn>.
-    There can be one or two sets of steps to perform,
-    covering when the promise is fulfilled, rejected, or both.
-    When a specification says to perform some steps once a promise is settled,
-    the following steps must be followed:
+    To <dfn id="dfn-perform-steps-once-promise-is-settled" export lt="upon settling">perform some steps once a promise is settled</dfn>,

Maybe move this below all the creation/resolve/reject operations, i.e. before "wait for all"

>      IDL [=promise type=] represents.
 </p>
 
 <div algorithm>
 
-    One can <dfn id="dfn-perform-steps-once-promise-is-settled" export lt="upon settling">perform some steps once a promise is settled</dfn>.
-    There can be one or two sets of steps to perform,
-    covering when the promise is fulfilled, rejected, or both.
-    When a specification says to perform some steps once a promise is settled,
-    the following steps must be followed:
+    To <dfn id="dfn-perform-steps-once-promise-is-settled" export lt="upon settling">perform some steps once a promise is settled</dfn>,

I think we should also add "upon fulfillment" and "upon rejection" shorthands.

>          1.  Let |R| be the first argument to |onRejected|.
         1.  Let |reason| be the result of [=converted to an IDL value|converting=]
             |R| to an IDL value of type {{any}}.
         1.  If there are no steps that are required to be run if the promise was rejected, then
             return <emu-val>undefined</emu-val>.
         1.  Otherwise, return the result of performing any steps that were required to be run if the promise was rejected,
             with |reason| as the rejection reason.
-    1.  Return [=!=] [$PerformPromiseThen$](|promise|, |onFulfilled|, |onRejected|).
+    1.  Let |onRejected| be [=!=] [$CreateBuiltinFunction$](|onRejectedSteps|, « »):
+    1.  Let |constructor| be |promise|.\[[Promise]].\[[Realm]].\[[Intrinsics]].[[{{%Promise%}}]].
+    1.  Let |newCapability| be ? [$NewPromiseCapability$](|constructor|).
+    1.  Return [=!=] [$PerformPromiseThen$](|promise|.\[[Promise]], |onFulfilled|, |onRejected|, |newCapability|).

You don't need to pass newCapability since it's unused. Just pass three arguments.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/heycam/webidl/pull/772#pullrequestreview-278688024

Received on Thursday, 22 August 2019 21:35:51 UTC