whatwg / dom

DOM Standard
https://dom.spec.whatwg.org/
Other
1.58k stars 295 forks source link

Proposal AbortSignal.prototype.filter(compare) #1280

Open mariusGundersen opened 6 months ago

mariusGundersen commented 6 months ago

What problem are you trying to solve?

There is now an AbortSignal.any([a, b, c]) that makes it possible to combine multiple signals, but there is currently no way to split a an AbortSignal. I therefore propose the instance method AbortSignal.prototype.filter(compare), which would return a new AbortSignal that only triggers if the reason matches some condition. For example:

function(signal){
  const timeoutSignal = signal.filter(reason => reason instanceof DOMException && reason.name === 'TimeoutError'); // only when the reason is a TimeoutError
}

The above example creates a signal that will only trigger if the reason matches that of AbortSignal.timeout(ms). If the reason doesn't match, then the returned signal will never trigger (since abort signals only ever trigger once).

What solutions exist today?

It is fairly easy to implement this today as a separate function (to not pollute the prototype):

function filterAbortReason(signal, compare) {
    if (signal.aborted && compare(signal.reason)) return AbortSignal.abort(signal.reason);
    const abortController = new AbortController();
    signal.addEventListener('abort', () => {
        if (compare(signal.reason)) {
            abortController.abort(signal.reason);
        }
    });
    return abortController.signal;
}

How would you solve it?

The above function could be placed on the AbortSignal prototype:

AbortSignal.prototype.filter = function(compare) {
    if (this.aborted && compare(this.reason)) return AbortSignal.abort(this.reason);
    const abortController = new AbortController();
    this.addEventListener('abort', () => {
        if (compare(this.reason)) {
            abortController.abort(this.reason);
        }
    });
    return abortController.signal;
}

Anything else?

No response

annevk commented 6 months ago

With proposals like this it helps to have some information about adoption in libraries, code in the wild, other languages with signals, questions on Stack Overflow, etc. I.e., a bit more data that demonstrates this is worth investing time in.

domenic commented 6 months ago

I don't think we should unilaterally add error filtering to AbortSignal; doing this for, e.g., Promise first seems more reasonable.

mariusGundersen commented 6 months ago

Do you mean adding filter to the Promise prototype? I didn't think AbortSignal inherited anything from promises? Or just copy the details of a Promise filter to AbortSignal later?

domenic commented 6 months ago

I mean, we have multiple primitives in the platform which forward errors to users. We shouldn't add a filtering method to just one. So yes, something similar to

Or just copy the details of a Promise filter to AbortSignal later?