Skip to content

Commit 0c2908a

Browse files
Merge pull request #143 from Pauan/improving-signals-1
2 parents e257333 + f2ba3d6 commit 0c2908a

File tree

2 files changed

+42
-32
lines changed

2 files changed

+42
-32
lines changed

.changeset/curvy-moose-shave.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@preact/signals-core": patch
3+
---
4+
5+
Simplify `batch()` to use a single flag instead of a counter

packages/core/src/index.ts

Lines changed: 37 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,7 @@
22
let currentSignal: Signal | undefined;
33
let commitError: Error | null = null;
44

5-
const pending = new Set<Signal>();
6-
/** Batch calls can be nested. 0 means that there is no batching */
7-
let batchPending = 0;
5+
let batchPending: Set<Signal> | null = null;
86

97
let oldDeps = new Set<Signal>();
108

@@ -71,25 +69,15 @@ export class Signal<T = any> {
7169

7270
if (this._value !== value) {
7371
this._value = value;
74-
let isFirst = pending.size === 0;
75-
pending.add(this);
76-
// in batch mode this signal may be marked already
77-
if (this._pending === 0) {
78-
mark(this);
79-
}
8072

81-
// this is the first change, not a computed and we are not
82-
// in batch mode:
83-
if (isFirst && batchPending === 0) {
84-
sweep(pending);
85-
pending.clear();
86-
if (commitError) {
87-
const err = commitError;
88-
// Clear global error flag for next commit
89-
commitError = null;
90-
throw err;
73+
batch(() => {
74+
batchPending!.add(this);
75+
76+
// in batch mode this signal may be marked already
77+
if (this._pending === 0) {
78+
mark(this);
9179
}
92-
}
80+
});
9381
}
9482
}
9583

@@ -205,7 +193,10 @@ const tmpPending: Signal[] = [];
205193
* we don't have to care about topological sorting.
206194
*/
207195
function refreshStale(signal: Signal) {
208-
pending.delete(signal);
196+
if (batchPending) {
197+
batchPending.delete(signal);
198+
}
199+
209200
signal._pending = 0;
210201
signal._updater();
211202
if (commitError) {
@@ -270,20 +261,34 @@ export function effect(callback: () => void) {
270261
}
271262

272263
export function batch<T>(cb: () => T): T {
273-
batchPending++;
274-
try {
264+
if (batchPending !== null) {
275265
return cb();
276-
} finally {
277-
// Since stale signals are refreshed upwards, we need to
278-
// add pending signals in reverse
279-
let item: Signal | undefined;
280-
while ((item = tmpPending.pop()) !== undefined) {
281-
pending.add(item);
282-
}
283266

284-
if (--batchPending === 0) {
267+
} else {
268+
const pending: Set<Signal> = new Set();
269+
270+
batchPending = pending;
271+
272+
try {
273+
return cb();
274+
275+
} finally {
276+
// Since stale signals are refreshed upwards, we need to
277+
// add pending signals in reverse
278+
let item: Signal | undefined;
279+
while ((item = tmpPending.pop()) !== undefined) {
280+
pending.add(item);
281+
}
282+
283+
batchPending = null;
284+
285285
sweep(pending);
286-
pending.clear();
286+
if (commitError) {
287+
const err = commitError;
288+
// Clear global error flag for next commit
289+
commitError = null;
290+
throw err;
291+
}
287292
}
288293
}
289294
}

0 commit comments

Comments
 (0)