MCPcopy
hub / github.com/sveltejs/svelte / async_derived

Function async_derived

packages/svelte/src/internal/client/reactivity/deriveds.js:113–283  ·  view source on GitHub ↗
(fn, label, location)

Source from the content-addressed store, hash-verified

111 */
112/*#__NO_SIDE_EFFECTS__*/
113export function async_derived(fn, label, location) {
114 let parent = /** @type {Effect | null} */ (active_effect);
115
116 if (parent === null) {
117 e.async_derived_orphan();
118 }
119
120 var promise = /** @type {Promise<V>} */ (/** @type {unknown} */ (undefined));
121 var signal = source(/** @type {V} */ (UNINITIALIZED));
122
123 if (DEV) signal.label = label ?? fn.toString();
124
125 // only suspend in async deriveds created on initialisation
126 var should_suspend = !active_reaction;
127
128 /** @type {Set<ReturnType<typeof deferred<V>>>} */
129 var deferreds = new Set();
130
131 async_effect(() => {
132 var effect = /** @type {Effect} */ (active_effect);
133
134 if (DEV) {
135 reactivity_loss_tracker = { effect, effect_deps: new Set(), warned: false };
136 }
137
138 /** @type {ReturnType<typeof deferred<V>>} */
139 var d = deferred();
140 promise = d.promise;
141
142 try {
143 // If this code is changed at some point, make sure to still access the then property
144 // of fn() to read any signals it might access, so that we track them as dependencies.
145 // We call `unset_context` to undo any `save` calls that happen inside `fn()`
146 Promise.resolve(fn())
147 .then(d.resolve, (e) => {
148 // if the promise was rejected by the user, via `getAbortSignal`, then
149 // wait for a subsequent resolution instead of flushing the batch
150 if (e !== STALE_REACTION) d.reject(e);
151 })
152 .finally(unset_context);
153 } catch (error) {
154 d.reject(error);
155 unset_context();
156 }
157
158 if (DEV) {
159 if (reactivity_loss_tracker) {
160 // Reused deps from previous run (indices 0 to skipped_deps-1)
161 // We deliberately only track direct dependencies of the async expression to encourage
162 // dependencies being directly visible at the point of the expression
163 if (effect.deps !== null) {
164 for (let i = 0; i < skipped_deps; i += 1) {
165 reactivity_loss_tracker.effect_deps.add(effect.deps[i]);
166 }
167 }
168
169 // New deps discovered this run
170 if (new_deps !== null) {

Callers 1

runFunction · 0.90

Calls 15

sourceFunction · 0.90
async_effectFunction · 0.90
deferredFunction · 0.90
unset_contextFunction · 0.90
increment_pendingFunction · 0.90
teardownFunction · 0.90
is_renderedMethod · 0.80
fnFunction · 0.70
handlerFunction · 0.70
nextFunction · 0.70
setMethod · 0.65
toStringMethod · 0.45

Tested by

no test coverage detected