Promise.finally not really final

Jon Ronnenberg jon.ronnenberg at gmail.com
Fri Sep 7 19:16:14 UTC 2018


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
,

t
a
p
into a
n
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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20180907/545b3f7e/attachment.html>


More information about the es-discuss mailing list