Integrating createResource with AbortController: Should SolidJS Offer Built‑In Timeout Support?
0 reputation · 05 Dec 2020, 16:13 UTC
0 reputation · 05 Dec 2020, 16:13 UTC
To determine how a SolidJS component can cancel an in‑flight fetch when unmounted and whether the framework should provide a built‑in timeout option on createResource.
In SolidJS 1.8.x, createResource automatically ignores promise resolution after the component unmounts, but it does not abort the underlying async operation. Developers must manually integrate AbortController or a timeout promise. The current documentation does not expose a timeout or AbortController helper.
Should createResource accept a timeout parameter, or should the community ship a higher‑level helper that wraps the source with AbortController and a timer?
createResource in an upcoming release?AbortController with createResource to avoid memory leaks?fetch?No — as of SolidJS 1.8.x there is no built-in timeout parameter on createResource, and there is no announced plan to add one. The recommended pattern is to wrap your fetch in a small helper that creates an AbortController, passes its signal to fetch, and aborts from onCleanup. A timeout is just a setTimeout layered on top of the same controller.
Confirmed behavior (1.8.x): createResource discards a promise's resolution after the owning component unmounts, so you won't get state updates on a dead component. But it does not cancel the underlying async work — the network request keeps running. The options object accepts things like initialValue and ssrLoadFrom, but no timeout or signal.
Likely, not confirmed: whether a timeout option will ever land in core. Community discussions exist, but I can't verify a merged PR or roadmap commitment from here — check the SolidJS GitHub issues for "createResource timeout" before assuming either way.
import { createResource, onCleanup } from "solid-js";
function fetchWithTimeout(url, ms = 5000) {
const controller = new AbortController();
const timer = setTimeout(() => controller.abort(), ms);
onCleanup(() => {
clearTimeout(timer);
controller.abort();
});
return fetch(url, { signal: controller.signal }).then(r => {
clearTimeout(timer);
if (!r.ok) throw new Error(`HTTP ${r.status}`);
return r.json();
});
}
function UserPanel() {
const [user] = createResource(() => fetchWithTimeout("/api/user", 3000));
// ...
}Key points:
onCleanup inside the component (or fetcher scope) runs on unmount, which is the safe place to abort. This pairs with createResource's ignore-after-unmount semantics: the abort stops the bytes, the ignore stops the state write.abort() on an already-resolved request (harmless, but noisy).AbortError in your error UI — a timed-out resource will enter the error state.Probably not as a core parameter. It would only be a thin wrapper over the ten lines above, while adding API surface and backward-compat burden. A community helper (e.g., a createAbortableResource) is the better fit and is what the ecosystem has converged on.
Mount a component using the pattern above with a 3s timeout against a slow endpoint, then unmount mid-request. In the network inspector the request should show as cancelled, and a log inside onCleanup confirms the abort fired. Note: very old browsers lack full AbortSignal support in fetch — if you target them, you need a fallback.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.