Skip to content

Commit 6d01285

Browse files
rakudramaCommit Queue
authored andcommitted
[js_runtime] Modernize and simplify _AsyncRun._scheduleImmediate.
Use browser's `queueMicrotask` if available. Remove `MutationObserver` method, since `queueMicrotask` is available on all supported browsers. Simplify by removing `internalCallback`. This is no longer needed (it used to do more than just call the callback). Issue: #20055 Change-Id: Ic866cdd77787fc45456f65a6618fe66afcbcb970 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/444392 Reviewed-by: Mayank Patke <[email protected]> Commit-Queue: Stephen Adams <[email protected]>
1 parent 5303070 commit 6d01285

File tree

1 file changed

+15
-58
lines changed

1 file changed

+15
-58
lines changed

sdk/lib/_internal/js_runtime/lib/async_patch.dart

Lines changed: 15 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ void _trySetStackTrace(Object error, StackTrace stackTrace) {
2626
}
2727
}
2828

29+
typedef _ScheduleImmediateFn = void Function(void Function());
30+
2931
@patch
3032
class _AsyncRun {
3133
@patch
@@ -34,78 +36,33 @@ class _AsyncRun {
3436
}
3537

3638
// Lazily initialized.
37-
static final Function _scheduleImmediateClosure =
39+
static final _ScheduleImmediateFn _scheduleImmediateClosure =
3840
_initializeScheduleImmediate();
3941

40-
static Function _initializeScheduleImmediate() {
42+
static _ScheduleImmediateFn _initializeScheduleImmediate() {
4143
requiresPreamble();
4244
if (JS('', 'self.scheduleImmediate') != null) {
4345
return _scheduleImmediateJsOverride;
4446
}
45-
if (JS('', 'self.MutationObserver') != null &&
46-
JS('', 'self.document') != null) {
47-
// Use mutationObservers.
48-
var div = JS('', 'self.document.createElement("div")');
49-
var span = JS('', 'self.document.createElement("span")');
50-
void Function()? storedCallback;
51-
52-
internalCallback(_) {
53-
var f = storedCallback;
54-
storedCallback = null;
55-
f!();
56-
}
5747

58-
var observer = JS(
59-
'',
60-
'new self.MutationObserver(#)',
61-
convertDartClosureToJS(internalCallback, 1),
62-
);
63-
JS('', '#.observe(#, { childList: true })', observer, div);
64-
65-
return (void callback()) {
66-
assert(storedCallback == null);
67-
storedCallback = callback;
68-
// Because of a broken shadow-dom polyfill we have to change the
69-
// children instead a cheap property.
70-
JS(
71-
'',
72-
'#.firstChild ? #.removeChild(#): #.appendChild(#)',
73-
div,
74-
div,
75-
span,
76-
div,
77-
span,
78-
);
79-
};
80-
} else if (JS('', 'self.setImmediate') != null) {
81-
return _scheduleImmediateWithSetImmediate;
48+
if (JS('', 'typeof self.queueMicrotask == "function"')) {
49+
return _scheduleImmediateWithQueueMicrotask;
8250
}
83-
// TODO(20055): We should use DOM promises when available.
51+
52+
// The fallback is not quite right as it uses the macro task queue.
8453
return _scheduleImmediateWithTimer;
8554
}
8655

8756
static void _scheduleImmediateJsOverride(void callback()) {
88-
internalCallback() {
89-
callback();
90-
}
91-
92-
JS(
93-
'void',
94-
'self.scheduleImmediate(#)',
95-
convertDartClosureToJS(internalCallback, 0),
96-
);
57+
JS('', 'self.scheduleImmediate(#)', convertDartClosureToJS(callback, 0));
9758
}
9859

99-
static void _scheduleImmediateWithSetImmediate(void callback()) {
100-
internalCallback() {
101-
callback();
102-
}
103-
104-
JS(
105-
'void',
106-
'self.setImmediate(#)',
107-
convertDartClosureToJS(internalCallback, 0),
108-
);
60+
/// `queueMicrotask` is available in all supported browsers in
61+
/// [windows](https://developer.mozilla.org/en-US/docs/Web/API/Window/queueMicrotask#browser_compatibility)
62+
/// and
63+
/// [workers](https://developer.mozilla.org/en-US/docs/Web/API/WorkerGlobalScope/queueMicrotask#browser_compatibility).
64+
static void _scheduleImmediateWithQueueMicrotask(void callback()) {
65+
JS('', 'self.queueMicrotask(#)', convertDartClosureToJS(callback, 0));
10966
}
11067

11168
static void _scheduleImmediateWithTimer(void callback()) {

0 commit comments

Comments
 (0)