Skip to content
This repository was archived by the owner on Sep 16, 2022. It is now read-only.

Commit 6e7118b

Browse files
committed
feat(Experimental): Add "longestPendingTimer" API.
This is not meant for broad use, and is experimental (and subject to change). PiperOrigin-RevId: 200714913
1 parent 072a5d6 commit 6e7118b

File tree

2 files changed

+41
-30
lines changed

2 files changed

+41
-30
lines changed

angular/lib/experimental.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import 'src/runtime.dart';
1919

2020
export 'src/bootstrap/modules.dart' show bootstrapLegacyModule;
2121
export 'src/core/linker/component_resolver.dart' show typeToFactory;
22+
export 'src/core/zone/ng_zone.dart' show longestPendingTimer;
2223

2324
/// Create a root (legacy, with `SlowComponentLoader`) application injector.
2425
///

angular/lib/src/core/zone/ng_zone.dart

Lines changed: 40 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import 'dart:async';
22

3+
import 'package:meta/meta.dart';
34
import 'package:stack_trace/stack_trace.dart';
45

56
// TODO: add/fix links to:
@@ -113,7 +114,7 @@ class NgZone {
113114

114115
// Number of microtasks pending from _innerZone (& descendants)
115116
int _pendingMicrotasks = 0;
116-
final List<Timer> _pendingTimers = <Timer>[];
117+
final _pendingTimers = <_WrappedTimer>[];
117118

118119
/// enabled in development mode as they significantly impact perf.
119120
NgZone({bool enableLongStackTrace = false}) {
@@ -234,28 +235,42 @@ class NgZone {
234235
}
235236

236237
Timer _createTimer(
237-
Zone self, ZoneDelegate parent, Zone zone, Duration duration, fn()) {
238+
Zone self,
239+
ZoneDelegate parent,
240+
Zone zone,
241+
Duration duration,
242+
void Function() fn,
243+
) {
238244
_WrappedTimer wrappedTimer;
239-
var cb = () {
245+
final onDone = () {
246+
_pendingTimers.remove(wrappedTimer);
247+
_setMacrotask(_pendingTimers.isNotEmpty);
248+
};
249+
final callback = () {
240250
try {
241251
fn();
242252
} finally {
243-
_pendingTimers.remove(wrappedTimer);
244-
_setMacrotask(_pendingTimers.isNotEmpty);
253+
onDone();
245254
}
246255
};
247-
Timer timer = parent.createTimer(zone, duration, cb);
248-
wrappedTimer = new _WrappedTimer(timer);
249-
wrappedTimer.addOnCancelCb(() {
250-
_pendingTimers.remove(wrappedTimer);
251-
_setMacrotask(_pendingTimers.isNotEmpty);
252-
});
253-
256+
Timer timer = parent.createTimer(zone, duration, callback);
257+
wrappedTimer = new _WrappedTimer(timer, duration, onDone);
254258
_pendingTimers.add(wrappedTimer);
255259
_setMacrotask(true);
256260
return wrappedTimer;
257261
}
258262

263+
/// **INTERNAL ONLY**: See [longestPendingTimer].
264+
Duration get _longestPendingTimer {
265+
var duration = Duration.zero;
266+
for (final timer in _pendingTimers) {
267+
if (timer._duration > duration) {
268+
duration = timer._duration;
269+
}
270+
}
271+
return duration;
272+
}
273+
259274
void _setMicrotask(bool hasMicrotasks) {
260275
_hasPendingMicrotasks = hasMicrotasks;
261276
_checkStable();
@@ -379,37 +394,32 @@ class NgZone {
379394
}
380395
}
381396

397+
/// For a [zone], returns the [Duration] of the longest pending timer.
398+
///
399+
/// If no timers are scheduled this will always return [Duration.zero].
400+
///
401+
/// **INTERNAL ONLY**: This is an experimental API subject to change.
402+
@experimental
403+
Duration longestPendingTimer(NgZone zone) => zone._longestPendingTimer;
404+
382405
/// A `Timer` wrapper that lets you specify additional functions to call when it
383406
/// is cancelled.
384407
class _WrappedTimer implements Timer {
385408
final Timer _timer;
386-
void Function() _onCancelCb;
409+
final Duration _duration;
410+
final void Function() _onCancel;
387411

388-
_WrappedTimer(this._timer);
389-
390-
void addOnCancelCb(void Function() onCancelCb) {
391-
if (this._onCancelCb != null) {
392-
throw new StateError("On cancel cb already registered");
393-
}
394-
this._onCancelCb = onCancelCb;
395-
}
412+
_WrappedTimer(this._timer, this._duration, this._onCancel);
396413

397414
void cancel() {
398-
if (this._onCancelCb != null) {
399-
this._onCancelCb();
400-
}
415+
_onCancel();
401416
_timer.cancel();
402417
}
403418

404419
bool get isActive => _timer.isActive;
405420

406421
@override
407-
// TODO: Dart 2.0 requires this method to be implemented.
408-
// See https://github.com/dart-lang/sdk/issues/31664
409-
// ignore: override_on_non_overriding_getter
410-
int get tick {
411-
throw new UnimplementedError("tick");
412-
}
422+
int get tick => _timer.tick;
413423
}
414424

415425
/// Stores error information; delivered via [NgZone.onError] stream.

0 commit comments

Comments
 (0)