chore: simplify batch logic (#16838)

* always delete a batch once committed

* activate inside flush

* centralise logic

* chore: simplify batch logic a bit more (#16845)

* more

* remove unnecessary flushSync

* simplify
pull/16847/head
Rich Harris 1 day ago committed by GitHub
parent f0cede6782
commit ed0a39345b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -22,7 +22,7 @@ import {
set_dev_current_component_function, set_dev_current_component_function,
set_dev_stack set_dev_stack
} from '../../context.js'; } from '../../context.js';
import { flushSync } from '../../reactivity/batch.js'; import { flushSync, is_flushing_sync } from '../../reactivity/batch.js';
const PENDING = 0; const PENDING = 0;
const THEN = 1; const THEN = 1;
@ -126,7 +126,7 @@ export function await_block(node, get_input, pending_fn, then_fn, catch_fn) {
// without this, the DOM does not update until two ticks after the promise // without this, the DOM does not update until two ticks after the promise
// resolves, which is unexpected behaviour (and somewhat irksome to test) // resolves, which is unexpected behaviour (and somewhat irksome to test)
flushSync(); if (!is_flushing_sync) flushSync();
} }
} }
} }

@ -10,10 +10,6 @@ function run_micro_tasks() {
run_all(tasks); run_all(tasks);
} }
export function has_pending_tasks() {
return micro_tasks.length > 0;
}
/** /**
* @param {() => void} fn * @param {() => void} fn
*/ */
@ -40,7 +36,7 @@ export function queue_micro_task(fn) {
* Synchronously run any queued tasks. * Synchronously run any queued tasks.
*/ */
export function flush_tasks() { export function flush_tasks() {
if (micro_tasks.length > 0) { while (micro_tasks.length > 0) {
run_micro_tasks(); run_micro_tasks();
} }
} }

@ -244,7 +244,6 @@ export async function async_body(fn) {
if (pending) { if (pending) {
batch.flush(); batch.flush();
} else { } else {
batch.activate();
batch.decrement(); batch.decrement();
} }

@ -23,7 +23,7 @@ import {
update_effect update_effect
} from '../runtime.js'; } from '../runtime.js';
import * as e from '../errors.js'; import * as e from '../errors.js';
import { flush_tasks, has_pending_tasks, queue_micro_task } from '../dom/task.js'; import { flush_tasks, queue_micro_task } from '../dom/task.js';
import { DEV } from 'esm-env'; import { DEV } from 'esm-env';
import { invoke_error_boundary } from '../error-handling.js'; import { invoke_error_boundary } from '../error-handling.js';
import { old_values } from './sources.js'; import { old_values } from './sources.js';
@ -216,15 +216,6 @@ export class Batch {
flush_queued_effects(render_effects); flush_queued_effects(render_effects);
flush_queued_effects(effects); flush_queued_effects(effects);
// Reinstate the current batch if there was no new one created, as `process()` runs in a loop in `flush_effects()`.
// That method expects `current_batch` to be set, and could run the loop again if effects result in new effects
// being scheduled but without writes happening in which case no new batch is created.
if (current_batch === null) {
current_batch = this;
} else {
batches.delete(this);
}
this.#deferred?.resolve(); this.#deferred?.resolve();
} else { } else {
this.#defer_effects(this.#render_effects); this.#defer_effects(this.#render_effects);
@ -365,19 +356,15 @@ export class Batch {
flush() { flush() {
if (queued_root_effects.length > 0) { if (queued_root_effects.length > 0) {
this.activate();
flush_effects(); flush_effects();
} else {
this.#commit();
}
if (current_batch !== this) { if (current_batch !== null && current_batch !== this) {
// this can happen if a `flushSync` occurred during `flush_effects()`, // this can happen if a new batch was created during `flush_effects()`
// which is permitted in legacy mode despite being a terrible idea
return; return;
} }
} else if (this.#pending === 0) {
if (this.#pending === 0) { this.#commit();
batches.delete(this);
} }
this.deactivate(); this.deactivate();
@ -394,6 +381,7 @@ export class Batch {
} }
this.#callbacks.clear(); this.#callbacks.clear();
batches.delete(this);
} }
increment() { increment() {
@ -478,14 +466,17 @@ export function flushSync(fn) {
var result; var result;
if (fn) { if (fn) {
if (current_batch !== null) {
flush_effects(); flush_effects();
}
result = fn(); result = fn();
} }
while (true) { while (true) {
flush_tasks(); flush_tasks();
if (queued_root_effects.length === 0 && !has_pending_tasks()) { if (queued_root_effects.length === 0) {
current_batch?.flush(); current_batch?.flush();
// we need to check again, in case we just updated an `$effect.pending()` // we need to check again, in case we just updated an `$effect.pending()`

Loading…
Cancel
Save