AbortSignal throwIfAborted
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.
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);
}
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
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK