Skip to content

Commit e1e04d0

Browse files
authored
fix: unset context on stale promises (slightly different approach) (#16936)
* slightly different approach to #16935 * move unset_context call
1 parent 489ccc0 commit e1e04d0

File tree

1 file changed

+6
-20
lines changed
  • packages/svelte/src/internal/client/reactivity

1 file changed

+6
-20
lines changed

packages/svelte/src/internal/client/reactivity/deriveds.js

Lines changed: 6 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -113,32 +113,24 @@ export function async_derived(fn, location) {
113113
// only suspend in async deriveds created on initialisation
114114
var should_suspend = !active_reaction;
115115

116-
/** @type {Map<Batch, ReturnType<typeof deferred<V>> & { rejected?: boolean }>} */
116+
/** @type {Map<Batch, ReturnType<typeof deferred<V>>>} */
117117
var deferreds = new Map();
118118

119119
async_effect(() => {
120120
if (DEV) current_async_effect = active_effect;
121121

122-
/** @type {ReturnType<typeof deferred<V>> & { rejected?: boolean }} */
122+
/** @type {ReturnType<typeof deferred<V>>} */
123123
var d = deferred();
124124
promise = d.promise;
125125

126126
try {
127127
// If this code is changed at some point, make sure to still access the then property
128128
// of fn() to read any signals it might access, so that we track them as dependencies.
129-
Promise.resolve(fn()).then((v) => {
130-
if (d.rejected) {
131-
// If we rejected this stale promise, d.resolve
132-
// is a noop (d.promise.then(handler) below will never run).
133-
// In this case we need to unset the restored context here
134-
// to avoid leaking it (and e.g. cause false-positive mutation errors).
135-
unset_context();
136-
} else {
137-
d.resolve(v);
138-
}
139-
}, d.reject);
129+
// We call `unset_context` to undo any `save` calls that happen inside `fn()`
130+
Promise.resolve(fn()).then(d.resolve, d.reject).then(unset_context);
140131
} catch (error) {
141132
d.reject(error);
133+
unset_context();
142134
}
143135

144136
if (DEV) current_async_effect = null;
@@ -151,11 +143,7 @@ export function async_derived(fn, location) {
151143
if (!pending) {
152144
batch.increment();
153145

154-
var previous_deferred = deferreds.get(batch);
155-
if (previous_deferred) {
156-
previous_deferred.rejected = true;
157-
previous_deferred.reject(STALE_REACTION);
158-
}
146+
deferreds.get(batch)?.reject(STALE_REACTION);
159147
deferreds.set(batch, d);
160148
}
161149
}
@@ -199,8 +187,6 @@ export function async_derived(fn, location) {
199187
boundary.update_pending_count(-1);
200188
if (!pending) batch.decrement();
201189
}
202-
203-
unset_context();
204190
};
205191

206192
d.promise.then(handler, (e) => handler(null, e || 'unknown'));

0 commit comments

Comments
 (0)