signal.throwIfAborted()
API throws signal’s abort reason, if signal’s AbortController has signaled to abort; otherwise, does nothing.
Quick Examples:
const signal = AbortSignal.abort(new Error("💣"))
signal.throwIfAborted()
function animationFrame(abortSignal) {
return new Promise((resolve, reject) => {
abortSignal?.throwIfAborted();
const frameRequest = requestAnimationFrame(time => resolve(time));
abortSignal?.addEventListener("abort", () => {
cancelAnimationFrame(frameRequest);
reject(new AbortError());
}, { once: true });
});
}
async function waitForCondition(func, targetValue, { signal } = {}) {
while (true) {
signal?.throwIfAborted();
const result = await func();
if (result === targetValue) {
return;
}
}
}
Signal-handling methods can use throwIfAborted
API to check a signal's abort status and propagate the abort reason, ex: async activities that might affect a signal's state.
Browser implementation:
Below is the crux from Firefox's implementation.
void AbortSignal::ThrowIfAborted(JSContext* aCx, ErrorResult& aRv) {
aRv.MightThrowJSException();
if (Aborted()) {
JS::Rooted<JS::Value> reason(aCx);
GetReason(aCx, &reason);
aRv.ThrowJSException(aCx, reason);
}
}
Safari is pretty similar:
void AbortSignal::throwIfAborted(JSC::JSGlobalObject& lexicalGlobalObject)
{
if (!aborted())
return;
auto& vm = lexicalGlobalObject.vm();
auto scope = DECLARE_THROW_SCOPE(vm);
throwException(&lexicalGlobalObject, scope, m_reason);
}
Chrome
void AbortSignal::throwIfAborted(ScriptState* script_state,
ExceptionState& exception_state) const {
if (!aborted())
return;
exception_state.RethrowV8Exception(reason(script_state).V8Value());
}
throwIfAborted() should:
- throw
abort.reason
if signal aborted - throw primitive
abort.reason
if signal aborted - should not throw if signal not aborted
Feel free to share this article. You may as well ping me on Twitter.
Published