Adding to a promise chain in the next frame is not uncommon. For instance, you 
may want to chain a procedure conditionally by some condition calculated 
against some data in indexeddb, where you cannot complete in the current 
tick(all indexeddb operations are async). There're more use cases when you are 
developing a library. It's true that most usages of promises is 'static', but 
promise is not limited to it. It can be used more dynamically.
For your use case, think of your target as to provide a destroy method with 
part of it injectable. You can just pass the code you want to inject in as a 
parameter, or give it a field to config. It's not so relevant to whether 
Promise.finally is really finally, because it cannot be done directly in 
traditional try..finally, either.




------------------ ???????? ------------------
??????: "Jon Ronnenberg"<[email protected]>;
????????: 2018??9??8??(??????) ????8:51
??????: "Augusto Moura"<[email protected]>;
????: "es-discuss"<[email protected]>; 
????: Re: Promise.finally not really final



> Why would you destroy a node and `.then()` pause it? It doesn't make
sense even in plain English. If the contract of the method (expected
behavior) is to destroy the internal node, using it after is a error.

The use case is a situation I am currently in, where I have a destroy function 
that is the same for 10 classes and I can not remove their DOM nodes myself 
because they are in an iframe and I'm coding against a black box API 
(proprietary).


Sometimes the removal fail or the DOM node is not removed due to performance 
optimization, not sure but my code needs to run regardless and updates to their 
API will happen long after I leave this project.


The symptom is that I can still hear the sound of video/audio, after it should 
have been removed.
 A few classes dealing with video and audio could add a `this.node.pause()` to 
the promise chain without changing the destroy trait or any other non audible 
dealing class.


There is many ways to implement this and I thought Promises would be an elegant 
implementation but since `finally` is called before `then`, even in the same 
call stack, a Promise is not useful.


I've never had a use for adding to a promise chain in the next frame, which is 
the main argument against calling finally at the end, so I might be the wrong 
audience.


I have demonstrated how it could work and I think it makes better sense but I'm 
not up for a fight to defend my way.


On Sat, 8 Sep 2018 01:18 Augusto Moura, <[email protected]> wrote:

Why would you destroy a node and `.then()` pause it? It doesn't make
 sense even in plain English. If the contract of the method (expected
 behavior) is to destroy the internal node, using it after is a error.
 You can easily reimplement your use case reversing the logic:
 
 ```` js
 setTimeout(() => {
   demo.node.pause();
   demo.destroy();
 }, 3000);
 ````
 
 Another solution is to implement a `beforeDestroy` event emitter and
 listen to it, this way is certain that the code will be executed
 always before the node is gone and after any async destroy logic:
 
 ```` js
 class Demo {
   constructor(el) {
     this.beforeDestroy = new EventEmitter();
     // Using the @angular/core EventEmitter because is more "close to English"
     this.node = el;
   }
   destroy() {
     return new Promise(resolve => resolve())
       .then(() => this.beforeDestroy.emit())
       .finally(() => {
         this.node = null;
       });
   }
 }
 
 const demo = new Demo(document.querySelector('video'));
 
 demo.beforeDestroy.subscribe(() => {
   demo.node.pause();
 });
 
 setTimeout(() => {
   demo.destroy();
 }, 3000);
 ````
 
 Anyway, the `then`, `catch` and `finally` methods mimic the serial
 try/catch/finally, simply doesn't make sense finally statements
 protecting code beyond it's try block definition, and chaining new
 `.then`s _are_ beyond the promise definition. Also, async functions
 already has finally blocks implementations in the same way as the
 current `.finally` method spec, implementing a different behaviour
 would be unnecessarily confusing.
 Em sex, 7 de set de 2018 ??s 16:16, Jon Ronnenberg
 <[email protected]> escreveu:
 >
 > I know I am late to the game and that Promise.prototype.finally is already 
 > in stage 4 but(!).
 >
 > It's just not very useful to have a final function when it's not the final 
 > function to run. If it's suppose to be for cleanup, then the current 
 > implementation is seriously lacking usefulness.
 >
 > Consider the following example:
 >
 > <audio
 >   class="i-am-the-element"
 >   autoplay="autoplay"
 >   controls="controls">
 >     <source type="audio/mp3" 
 > src="http:\/\/play.dogmazic.net\/play\/index.php?type=song&oid=22951&uid=-1&name=Black%20poetry%20-%20Aime-.mp3">
 > </audio>
 > <script>
 >   class Demo {
 >     constructor (element) {
 >       this.node = element
 >     }
 >     destroy () {
 >       return new Promise(resolve => {
 >         // do something or nothing
 >         resolve()
 >       }).finally(() => {
 >         // schedule for DOM removal
 >         this.node = null
 >       })
 >     }
 >   }
 >
 >   const demo = new Demo(document.querySelector('.i-am-the-element'))
 >
 >   setTimeout(() => {
 >     demo.destroy().then(() => {
 >    // will throw an error because finally was run before
 >       demo.node.pause()
 >     }).catch(console.error)
 >   }, 3000)
 > </script>
 >
 > One grand idea about promises is to delegate and compose asynchronous 
 > functions, but the current implementation can not be used to for code 
 > delegation.
 >
 > From the top of my head the only way to have consumer code,  tap into an 
 > execution process is to use callbacks which is what Promises were suppose to 
 > help alleviate.
 >
 > <audio
 >   class="i-am-the-element"
 >   autoplay="autoplay"
 >   controls="controls">
 >     <source type="audio/mp3" 
 > src="http:\/\/play.dogmazic.net\/play\/index.php?type=song&oid=22951&uid=-1&name=Black%20poetry%20-%20Aime-.mp3">
 > </audio>
 > <script>
 >   class Demo {
 >     constructor (element) {
 >       this.node = element
 >     }
 >     destroy (callback) {
 >       // do something or nothing
 >       try {
 >         callback()
 >       } finally {
 >         // schedule for DOM removal
 >         this.node = null
 >       }
 >     }
 >   }
 >
 >   const demo = new Demo(document.querySelector('.i-am-the-element'))
 >
 >   setTimeout(() => {
 >     demo.destroy(() => {
 >       demo.node.pause()
 >     })
 >   }, 3000)
 > </script>
 >
 > If at all possible, please amend to the spec before it's too late! ... or 
 > just drop it.
 >
 > My current use-case is that I work with PSPDFKit and can not get DOM access 
 > but rather schedule removal of DOM nodes via their API, but I can pause 
 > audio/video - just not using Promise.prototype.finally as it is currently 
 > envisioned.
 >
 > Regards, Jon
 >
 > PS. Tested in Firefox 63.0b3 and Safari 11.1.2
 > Here is a polyfill if you need: 
 > https://cdn.polyfill.io/v2/polyfill.minify.js?features=Promise.prototype.finally&amp;flags=gated
 >
 > _______________________________________________
 > es-discuss mailing list
 > [email protected]
 > https://mail.mozilla.org/listinfo/es-discuss
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to