The promise disposer pattern works basically like this:
```js
// Promise chain
function withFoo(init) {
return getFoo().then(foo =>
Promise.resolve()
.then(() => init(foo))
.finally(() => foo.destroy())
)
}
// Async function
async function withFoo(init) {
const foo = await getFoo()
try {
return await init(foo)
} finally {
await foo.destroy()
}
}
// Example use
withFoo(async foo => {
await foo.changeThings()
return foo.getValue()
})
```
That's one big place where this is useful.
On Fri, Sep 7, 2018 at 19: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&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
>
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss