Fwd: Promise.finally not really final

Jon Ronnenberg jon.ronnenberg at gmail.com
Fri Sep 7 19:25:29 UTC 2018


Sorry for re-posting but wanted to send this plain-text and didn't
figure out that "remove formatting" in gmail wasn't it.
I hope everyone can read this now :)

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


More information about the es-discuss mailing list