chore: unify async logic (#17731)

We have a bunch of repeated logic around incrementing/decrementing
pending states. This DRYs it out to unblock some forthcoming changes
around scheduling
pull/17733/head
Rich Harris 6 months ago committed by GitHub
parent bd4ba56932
commit 3f6521df0e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -1,6 +1,5 @@
/** @import { Blocker, TemplateNode, Value } from '#client' */
import { flatten } from '../../reactivity/async.js';
import { Batch, current_batch } from '../../reactivity/batch.js';
import { flatten, increment_pending } from '../../reactivity/async.js';
import { get } from '../../runtime.js';
import {
hydrate_next,
@ -10,7 +9,6 @@ import {
set_hydrating,
skip_nodes
} from '../hydration.js';
import { get_boundary } from './boundary.js';
/**
* @param {TemplateNode} node
@ -44,12 +42,7 @@ export function async(node, blockers = [], expressions = [], fn) {
return;
}
var boundary = get_boundary();
var batch = /** @type {Batch} */ (current_batch);
var blocking = boundary.is_rendered();
boundary.update_pending_count(1);
batch.increment(blocking);
const decrement_pending = increment_pending();
if (was_hydrating) {
var previous_hydrate_node = hydrate_node;
@ -72,8 +65,7 @@ export function async(node, blockers = [], expressions = [], fn) {
set_hydrating(false);
}
boundary.update_pending_count(-1);
batch.decrement(blocking);
decrement_pending();
}
});
}

@ -452,10 +452,6 @@ export class Boundary {
}
}
export function get_boundary() {
return /** @type {Boundary} */ (/** @type {Effect} */ (active_effect).b);
}
export function pending() {
if (active_effect === null) {
e.effect_pending_outside_reaction();

@ -8,7 +8,7 @@ import {
set_component_context,
set_dev_stack
} from '../context.js';
import { get_boundary } from '../dom/blocks/boundary.js';
import { Boundary } from '../dom/blocks/boundary.js';
import { invoke_error_boundary } from '../error-handling.js';
import {
active_effect,
@ -224,12 +224,7 @@ export function unset_context() {
export function run(thunks) {
const restore = capture();
var boundary = get_boundary();
var batch = /** @type {Batch} */ (current_batch);
var blocking = boundary.is_rendered();
boundary.update_pending_count(1);
batch.increment(blocking);
const decrement_pending = increment_pending();
var active = /** @type {Effect} */ (active_effect);
@ -286,10 +281,7 @@ export function run(thunks) {
// wait one more tick, so that template effects are
// guaranteed to run before `$effect(...)`
.then(() => Promise.resolve())
.finally(() => {
boundary.update_pending_count(-1);
batch.decrement(blocking);
});
.finally(decrement_pending);
return blockers;
}
@ -300,3 +292,17 @@ export function run(thunks) {
export function wait(blockers) {
return Promise.all(blockers.map((b) => b.promise));
}
export function increment_pending() {
var boundary = /** @type {Boundary} */ (/** @type {Effect} */ (active_effect).b);
var batch = /** @type {Batch} */ (current_batch);
var blocking = boundary.is_rendered();
boundary.update_pending_count(1);
batch.increment(blocking);
return () => {
boundary.update_pending_count(-1);
batch.decrement(blocking);
};
}

@ -40,7 +40,7 @@ import { Boundary } from '../dom/blocks/boundary.js';
import { component_context } from '../context.js';
import { UNINITIALIZED } from '../../../constants.js';
import { batch_values, current_batch } from './batch.js';
import { unset_context } from './async.js';
import { increment_pending, unset_context } from './async.js';
import { deferred, includes, noop } from '../../shared/utils.js';
import { set_signal_status, update_derived_status } from './status.js';
@ -111,8 +111,6 @@ export function async_derived(fn, label, location) {
e.async_derived_orphan();
}
var boundary = /** @type {Boundary} */ (parent.b);
var promise = /** @type {Promise<V>} */ (/** @type {unknown} */ (undefined));
var signal = source(/** @type {V} */ (UNINITIALIZED));
@ -156,10 +154,7 @@ export function async_derived(fn, label, location) {
var batch = /** @type {Batch} */ (current_batch);
if (should_suspend) {
var blocking = boundary.is_rendered();
boundary.update_pending_count(1);
batch.increment(blocking);
var decrement_pending = increment_pending();
deferreds.get(batch)?.reject(STALE_REACTION);
deferreds.delete(batch); // delete to ensure correct order in Map iteration below
@ -208,9 +203,8 @@ export function async_derived(fn, label, location) {
}
}
if (should_suspend) {
boundary.update_pending_count(-1);
batch.decrement(blocking);
if (decrement_pending) {
decrement_pending();
}
};

@ -40,8 +40,8 @@ import { DEV } from 'esm-env';
import { define_property } from '../../shared/utils.js';
import { get_next_sibling } from '../dom/operations.js';
import { component_context, dev_current_component_function, dev_stack } from '../context.js';
import { Batch, current_batch, schedule_effect } from './batch.js';
import { flatten } from './async.js';
import { Batch, schedule_effect } from './batch.js';
import { flatten, increment_pending } from './async.js';
import { without_reactive_context } from '../dom/elements/bindings/shared.js';
import { set_signal_status } from './status.js';
@ -376,14 +376,16 @@ export function template_effect(fn, sync = [], async = [], blockers = []) {
* @param {Blocker[]} blockers
*/
export function deferred_template_effect(fn, sync = [], async = [], blockers = []) {
var batch = /** @type {Batch} */ (current_batch);
var is_async = async.length > 0 || blockers.length > 0;
if (is_async) batch.increment(true);
if (async.length > 0 || blockers.length > 0) {
var decrement_pending = increment_pending();
}
flatten(blockers, sync, async, (values) => {
create_effect(EFFECT, () => fn(...values.map(get)), false);
if (is_async) batch.decrement(true);
if (decrement_pending) {
decrement_pending();
}
});
}

Loading…
Cancel
Save