Proposal for Promise.prototype.flatten

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Proposal for Promise.prototype.flatten

Aaron Silvas
https://github.com/asilvas/proposal-promise-flatten 

Looking for interest, and TC39 champion.

The basic idea is to provide a simpler, more consistent interface, and easier to read code over using try/catches for async code paths. Regardless of which errors are handled or ignored, it's treated as nothing more than another input in the result, not all that dissimilar to callbacks.

async function test(promise1, promise2, promise3) {
  const [, val1] = await promise1.flatten(); // ignore exceptions
  const [err, [val2, val3] = []] = await Promise.all([promise2, promise3]).flatten();

  if (err) throw err; // throw to caller

  return val1 + val2 + val3;
}

Original topic that spurred interest in this pattern: https://twitter.com/DavidWells/status/1119729914876284928



Thanks,

Aaron

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Proposal for Promise.prototype.flatten

guest271314
The term "flatten" or "flatmap" has also been used to refer to "flattening" a nested array; and/or "flattening" (output) of a potentially (arbitrarily) nested data structure (synchronous and asynchronous input/output). 

"easier to read" is subjective; depends on the expectations of the reader. try..catch blocks could be considered explicitly "easier to read" by the names used: "try"; "catch".

The requirement appears to be a "reflect" pattern? E.g., see this answer https://stackoverflow.com/a/31424853 at Wait until all ES6 promises complete, even rejected promises

const reflect = p => p.then(v => ({v, status: "fulfilled" }),
                            e => ({e, status: "rejected" }));

reflect(promise).then((v => {
    console.log(v.status);
});
Is the expected result to write less code and handle exceptions implicitly?

On Tue, Apr 23, 2019 at 8:25 PM Aaron Silvas <[hidden email]> wrote:
https://github.com/asilvas/proposal-promise-flatten 

Looking for interest, and TC39 champion.

The basic idea is to provide a simpler, more consistent interface, and easier to read code over using try/catches for async code paths. Regardless of which errors are handled or ignored, it's treated as nothing more than another input in the result, not all that dissimilar to callbacks.

async function test(promise1, promise2, promise3) {
  const [, val1] = await promise1.flatten(); // ignore exceptions
  const [err, [val2, val3] = []] = await Promise.all([promise2, promise3]).flatten();

  if (err) throw err; // throw to caller

  return val1 + val2 + val3;
}

Original topic that spurred interest in this pattern: https://twitter.com/DavidWells/status/1119729914876284928



Thanks,

Aaron
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Proposal for Promise.prototype.flatten

Jordan Harband
In reply to this post by Aaron Silvas
Would this not work?
async function test(promise1, promise2, promise3) {
  const val1 = await promise1.catch(); // ignore exceptions
  const [val2, val3] = [] = await Promise.all([promise2, promise3]).catch();

  await Promise.all([promise1, promise2, promise3]); // throw to caller

  return val1 + val2 + val3;
}

On Tue, Apr 23, 2019 at 1:25 PM Aaron Silvas <[hidden email]> wrote:
https://github.com/asilvas/proposal-promise-flatten 

Looking for interest, and TC39 champion.

The basic idea is to provide a simpler, more consistent interface, and easier to read code over using try/catches for async code paths. Regardless of which errors are handled or ignored, it's treated as nothing more than another input in the result, not all that dissimilar to callbacks.

async function test(promise1, promise2, promise3) {
  const [, val1] = await promise1.flatten(); // ignore exceptions
  const [err, [val2, val3] = []] = await Promise.all([promise2, promise3]).flatten();

  if (err) throw err; // throw to caller

  return val1 + val2 + val3;
}

Original topic that spurred interest in this pattern: https://twitter.com/DavidWells/status/1119729914876284928



Thanks,

Aaron
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Proposal for Promise.prototype.flatten

Bergi
In reply to this post by Aaron Silvas
Hello,

I oppose this proposal.

In my opinion, mixing normal exceptions (promise rejections) with
result-error-tuples is rather inconsistent than a more consistent
interface. The only thing it might interface better with are
node.js-style callbacks, but we already deprecated those in favour of
promises.
`if (err) throw err;` is reminiscent of this old style, it's no longer
necessary to explicitly re-throw with modern syntax.

It's not even simpler, or better to read. The example you gave could
easier be written as
```js
async function test(promise1, promise2, promise3) {
   const val1 = await promise1.catch(err => void err); // ignore exceptions
   const [val2, val3] = await Promise.all([promise2, promise3]); //
throw to caller

   return val1 + val2 + val3;
}
```
(Notice also that no default value for the destructuring is necessary,
which is a rather error-prone part of your snippet). Using `catch`
forces the programmer into explicitly providing a default value (even if
`undefined`), which could go unnoticed otherwise.
Can you please add an example where using `.flatten()` actually
introduces an advantage?

If one needs a more powerful error handling approach, you should use
`then` with two callbacks. (Getting a try-catch-else syntax
<https://stackoverflow.com/questions/4872170/javascript-try-catch-else-finally-like-python-java-ruby-etc>
for that would be nice, though).

As already mentioned, the name `flatten` is ill-suited for this method.

If you absolutely need this functionality, use `.then(r=>[,r],e=>[e])`
in your code, or put it inside a helper function. (Or use one from  a
library like <https://github.com/scopsy/await-to-js/>).
We do not need this as a method in the EcmaScript standard.

best regards,
  Bergi
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss