Skip to content

Commit db35611

Browse files
authored
Schedule tasks which are futures to completion (#112269)
1 parent 98c0498 commit db35611

File tree

2 files changed

+32
-3
lines changed

2 files changed

+32
-3
lines changed

packages/flutter/lib/src/scheduler/binding.dart

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ typedef FrameCallback = void Function(Duration timeStamp);
5050
///
5151
/// The type argument `T` is the task's return value. Consider `void` if the
5252
/// task does not return a value.
53-
typedef TaskCallback<T> = T Function();
53+
typedef TaskCallback<T> = FutureOr<T> Function();
5454

5555
/// Signature for the [SchedulerBinding.schedulingStrategy] callback. Called
5656
/// whenever the system needs to decide whether a task at a given
@@ -409,8 +409,12 @@ mixin SchedulerBinding on BindingBase {
409409
}
410410
final PriorityQueue<_TaskEntry<dynamic>> _taskQueue = HeapPriorityQueue<_TaskEntry<dynamic>>(_taskSorter);
411411

412-
/// Schedules the given `task` with the given `priority` and returns a
413-
/// [Future] that completes to the `task`'s eventual return value.
412+
/// Schedules the given `task` with the given `priority`.
413+
///
414+
/// If `task` returns a future, the future returned by [scheduleTask] will
415+
/// complete after the former future has been scheduled to completion.
416+
/// Otherwise, the returned future for [scheduleTask] will complete with the
417+
/// same value returned by `task` after it has been scheduled.
414418
///
415419
/// The `debugLabel` and `flow` are used to report the task to the [Timeline],
416420
/// for use when profiling.

packages/flutter/test/scheduler/scheduler_test.dart

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,31 @@ void main() {
250250
warmUpDrawFrame();
251251
expect(scheduler.hasScheduledFrame, isTrue);
252252
});
253+
254+
test('Can schedule futures to completion', () async {
255+
bool isCompleted = false;
256+
257+
// `Future` is disallowed in this file due to the import of
258+
// scheduler_tester.dart so annotations cannot be specified.
259+
// ignore: always_specify_types
260+
final result = scheduler.scheduleTask(
261+
() async {
262+
// Yield, so if awaiting `result` did not wait for completion of this
263+
// task, the assertion on `isCompleted` will fail.
264+
await null;
265+
await null;
266+
267+
isCompleted = true;
268+
return 1;
269+
},
270+
Priority.idle,
271+
);
272+
273+
scheduler.handleEventLoopCallback();
274+
await result;
275+
276+
expect(isCompleted, true);
277+
});
253278
}
254279

255280
class DummyTimer implements Timer {

0 commit comments

Comments
 (0)