Skip to content

Commit

Permalink
Adds SyncScheduler.
Browse files Browse the repository at this point in the history
This is a `Scheduler` implementation which immediately invokes any scheduled action synchronously.

I'm not 100% this is a good idea at this stage, but the current expected use is for one component to synchronously communicate changes another so DOM operations across all of them can be batched together in a single async task scheduled via `setTimeout` / `requestAnimationFrame`. If each component used `setTimeout`, then each component's DOM operaitons would be independently scheduled one macrotask apart from each other and result in unnecessary DOM thrashing.
  • Loading branch information
dgp1130 committed Dec 2, 2024
1 parent 703b743 commit 5dd1efc
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 0 deletions.
8 changes: 8 additions & 0 deletions src/signals/schedulers/sync-scheduler.test.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<!DOCTYPE html>
<html>
<head>
<title>`sync-scheduler` tests</title>
<meta charset="utf8">
</head>
<body></body>
</html>
22 changes: 22 additions & 0 deletions src/signals/schedulers/sync-scheduler.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { Action } from './scheduler.js';
import { syncScheduler } from './sync-scheduler.js';

describe('sync-scheduler', () => {
describe('SyncScheduler', () => {
describe('schedule', () => {
it('executes the given action synchronously', () => {
const action = jasmine.createSpy<Action>('action');

syncScheduler.schedule(action);
expect(action).toHaveBeenCalledOnceWith();
});

it('ignores cancel operations', () => {
const action = jasmine.createSpy<Action>('action');

const cancel = syncScheduler.schedule(action);
expect(cancel).not.toThrow();
});
});
});
});
15 changes: 15 additions & 0 deletions src/signals/schedulers/sync-scheduler.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { Action, CancelAction, Scheduler } from './scheduler.js';

/**
* A {@link Scheduler} implementation which always executes operations
* synchronously, immediately when scheduled.
*/
class SyncScheduler implements Scheduler {
public schedule(action: Action): CancelAction {
action();
return () => {};
}
}

/** Singleton {@link SyncScheduler} for shared usage. */
export const syncScheduler = new SyncScheduler();

0 comments on commit 5dd1efc

Please sign in to comment.