Interesting. I have a proof of concept that would let you do this:

```js
new Promise(res => setTimeout(res, 1000, 'OK'))
  .addListeners(console.log, console.error);
```

and you could drop that listener at any time via the following test:
```js
new Promise(res => setTimeout(res, 1000, 'OK'))
  .addListeners(console.log, console.error)
  .removeListners(console.log);
```

The two methods are here:

```js
const wm = new WeakMap;
Object.defineProperties(
  Promise.prototype,
  {
    addListeners: {
      configurable: true,
      value(resolve, reject) {
        let once = wm.get(this);
        if (!once) {
          wm.set(this, once = this.then(
            result => once.resolve.forEach(fn => fn(result)),
            error => once.reject.forEach(fn => fn(error))
          ));
          once.resolve = [];
          once.reject = [];
        }
        if (resolve && !once.resolve.includes(resolve))
          once.resolve.push(resolve);
        if (reject && !once.reject.includes(reject))
          once.reject.push(reject);
        return this;
      }
    },
    removeListeners: {
      configurable: true,
      value(resolve, reject) {
        const once = wm.get(this);
        if (once) {
          if (resolve) {
            const i = once.resolve.indexOf(resolve);
            if (-1 < i) once.resolve.splice(i, 1);
          }
          if (reject) {
            const i = once.reject.indexOf(reject);
            if (-1 < i) once.reject.splice(i, 1);
          }
        }
        return this;
      }
    }
  }
);
```

On Mon, Apr 23, 2018 at 7:56 PM, Oliver Dunk <oli...@oliverdunk.com> wrote:

> My proposal is that we add a way of removing a particular callback, or all
> callbacks, from a Promise. This is different to cancelling a Promise and
> would instead happen if you want the operation to continue but are no
> longer interested in running a function when the Promise is resolved or
> rejected.
>
> This would be implemented in two ways. The first I believe to be most
> useful, and the second is a sort of “sub-proposal”, that I would be happy
> to leave out:
>
> 1. A new `Promise.prototype.clear()` method. This would remove all
> callbacks currently added to a Promise.
> 2. A `Promise.prototype.clear(promise)` method, which takes the Promise
> returned when `Promise.prototype.then()` or `Promise.prototype.catch()` was
> called. This would remove that specific callback leaving any others. I
> don’t know if another argument would make better sense here? Maybe an
> identifier to the one used in `clearInterval()`.
>
> The use case that I see for this is for a Promise equivalent to
> `EventTarget.removeEventListener()`.
>
> I look forward to hearing feedback on this. I am new to the process here
> and so am open to any advice and am happy to make changes on this if there
> is an approach that would be considered better practice.
> _______________________________________________
> es-discuss mailing list
> es-discuss@mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
_______________________________________________
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to