4

AbortSignal throwIfAborted

 2 years ago
source link: https://h3manth.com/posts/abortsignal-throwIfAborted/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

AbortSignal throwIfAborted

2 min read.

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("💣"))
/*AbortSignal {aborted: true, reason: Error: 💣
at <anonymous>:1:28, onabort: null} */
signal.throwIfAborted()

/*
VM74:1 Uncaught Error: 💣
at <anonymous>:1:28
*/
// From the issues
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 });
});
}
// From the spec
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.

// https://dom.spec.whatwg.org/#dom-abortsignal-throwifaborted
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 07 Apr 2022


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK