Promise finally

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

Promise finally

Raul-Sebastian Mihăilă
I find it weird that

```js
Promise.resolve().finally(() => {}).then(() => { console.log(1); });
Promise.resolve().then(() => {}).then(() => { console.log(2); });
```

prints 2 and then 1. It would have been possible to spec it in such a way that it would have printed 1 and 2.

On the other hand

```js
Promise.resolve().finally().then(() => { console.log(1); });
Promise.resolve().then().then(() => { console.log(2); });
```

prints 1 and then 2.

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

Re: Promise finally

Viktor Kronvall
Since these two Promises aren't chained to one another I wouldn't expect any specific
deterministic ordering between the `console.log` statements. Are you suggesting that
such a deterministic ordering should be imposed by using micro tasks or what are you
proposing here exactly?

In other words, why exactly do you expect the result to always be printing 1 before
printing 2?

2018年2月23日(金) 19:21 Raul-Sebastian Mihăilă <[hidden email]>:
I find it weird that

```js
Promise.resolve().finally(() => {}).then(() => { console.log(1); });
Promise.resolve().then(() => {}).then(() => { console.log(2); });
```

prints 2 and then 1. It would have been possible to spec it in such a way that it would have printed 1 and 2.

On the other hand

```js
Promise.resolve().finally().then(() => { console.log(1); });
Promise.resolve().then().then(() => { console.log(2); });
```

prints 1 and then 2.
_______________________________________________
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: Promise finally

Raul-Sebastian Mihăilă
The order is deterministic, as specified, I just don't think it's the right order. I don't have a concrete example with finally, but if I were to imagine one, say you're writing some tests with jest and you want to make some checks in the then callbacks. In order for those checks to be executed in good time, you must return a promise from the test callback. If you have more promises you have to do a Promise.all in order to make sure that you wait for all the promises. If you are able to determine the order in which the promises are settled, you can return the one that is settled the last. This is perhaps not a convincing example, but if this didn't matter why is the order specified?

On Fri, Feb 23, 2018 at 3:59 PM, Viktor Kronvall <[hidden email]> wrote:
Since these two Promises aren't chained to one another I wouldn't expect any specific
deterministic ordering between the `console.log` statements. Are you suggesting that
such a deterministic ordering should be imposed by using micro tasks or what are you
proposing here exactly?

In other words, why exactly do you expect the result to always be printing 1 before
printing 2?

2018年2月23日(金) 19:21 Raul-Sebastian Mihăilă <[hidden email]>:
I find it weird that

```js
Promise.resolve().finally(() => {}).then(() => { console.log(1); });
Promise.resolve().then(() => {}).then(() => { console.log(2); });
```

prints 2 and then 1. It would have been possible to spec it in such a way that it would have printed 1 and 2.

On the other hand

```js
Promise.resolve().finally().then(() => { console.log(1); });
Promise.resolve().then().then(() => { console.log(2); });
```

prints 1 and then 2.
_______________________________________________
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: Promise finally

Michael Luder-Rosefield
Whenever you chain a promise with a then/finally, you're basically letting the runtime look at the callbacks at some arbitrary point in the future, no? So despite being written in a defined order, they will be run in whatever order eventuates.

On Fri, 23 Feb 2018 at 14:24 Raul-Sebastian Mihăilă <[hidden email]> wrote:
The order is deterministic, as specified, I just don't think it's the right order. I don't have a concrete example with finally, but if I were to imagine one, say you're writing some tests with jest and you want to make some checks in the then callbacks. In order for those checks to be executed in good time, you must return a promise from the test callback. If you have more promises you have to do a Promise.all in order to make sure that you wait for all the promises. If you are able to determine the order in which the promises are settled, you can return the one that is settled the last. This is perhaps not a convincing example, but if this didn't matter why is the order specified?

On Fri, Feb 23, 2018 at 3:59 PM, Viktor Kronvall <[hidden email]> wrote:
Since these two Promises aren't chained to one another I wouldn't expect any specific
deterministic ordering between the `console.log` statements. Are you suggesting that
such a deterministic ordering should be imposed by using micro tasks or what are you
proposing here exactly?

In other words, why exactly do you expect the result to always be printing 1 before
printing 2?

2018年2月23日(金) 19:21 Raul-Sebastian Mihăilă <[hidden email]>:
I find it weird that

```js
Promise.resolve().finally(() => {}).then(() => { console.log(1); });
Promise.resolve().then(() => {}).then(() => { console.log(2); });
```

prints 2 and then 1. It would have been possible to spec it in such a way that it would have printed 1 and 2.

On the other hand

```js
Promise.resolve().finally().then(() => { console.log(1); });
Promise.resolve().then().then(() => { console.log(2); });
```

prints 1 and then 2.
_______________________________________________
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

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

Re: Promise finally

Boris Zbarsky
On 2/23/18 9:30 AM, Michael Luder-Rosefield wrote:
> Whenever you chain a promise with a then/finally, you're basically
> letting the runtime look at the callbacks at some arbitrary point in the
> future, no?

Not if the promise is already known to be resolved.  In that case, the
exact behavior of the runtime is very clearly specified.

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

Re: Promise finally

Ben Newman
This ordering of `console.log` calls seems to happen because `Promise.prototype.finally` is specified in terms of `Promise.prototype.then`, and is required to call `.then` twice.

Note the `Invoke(promise, "then", « thenFinally, catchFinally »)` here, followed by `Invoke(promise, "then", « ... »)` here (and here).

Any way you cut it, this adds an extra asynchronous tick/step/hop/skip/jump, compared to merely calling `Promise.prototype.then`.

Implementing `Promise` extensions in terms of `Promise.prototype.then` is a good idea, because it means we don't have to add new fundamental operations to the core `Promise` implementation. However, the translation from `.finally` to `.then` comes at a cost. Once you understand that tradeoff, hopefully this behavior seems more reasonable.

Ben

His errors are volitional and are the portals of discovery.
-- James Joyce

On Fri, Feb 23, 2018 at 9:32 AM, Boris Zbarsky <[hidden email]> wrote:
On 2/23/18 9:30 AM, Michael Luder-Rosefield wrote:
Whenever you chain a promise with a then/finally, you're basically letting the runtime look at the callbacks at some arbitrary point in the future, no?

Not if the promise is already known to be resolved.  In that case, the exact behavior of the runtime is very clearly specified.

-Boris

_______________________________________________
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