From db35611ececa511140e4e062b5b1906c714ea2cc Mon Sep 17 00:00:00 2001 From: Jia Hao Date: Thu, 6 Oct 2022 23:23:53 +0800 Subject: [PATCH] Schedule tasks which are futures to completion (#112269) --- .../flutter/lib/src/scheduler/binding.dart | 10 +++++--- .../test/scheduler/scheduler_test.dart | 25 +++++++++++++++++++ 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/packages/flutter/lib/src/scheduler/binding.dart b/packages/flutter/lib/src/scheduler/binding.dart index a74ddd2dda..97ae86a35f 100644 --- a/packages/flutter/lib/src/scheduler/binding.dart +++ b/packages/flutter/lib/src/scheduler/binding.dart @@ -50,7 +50,7 @@ typedef FrameCallback = void Function(Duration timeStamp); /// /// The type argument `T` is the task's return value. Consider `void` if the /// task does not return a value. -typedef TaskCallback = T Function(); +typedef TaskCallback = FutureOr Function(); /// Signature for the [SchedulerBinding.schedulingStrategy] callback. Called /// whenever the system needs to decide whether a task at a given @@ -409,8 +409,12 @@ mixin SchedulerBinding on BindingBase { } final PriorityQueue<_TaskEntry> _taskQueue = HeapPriorityQueue<_TaskEntry>(_taskSorter); - /// Schedules the given `task` with the given `priority` and returns a - /// [Future] that completes to the `task`'s eventual return value. + /// Schedules the given `task` with the given `priority`. + /// + /// If `task` returns a future, the future returned by [scheduleTask] will + /// complete after the former future has been scheduled to completion. + /// Otherwise, the returned future for [scheduleTask] will complete with the + /// same value returned by `task` after it has been scheduled. /// /// The `debugLabel` and `flow` are used to report the task to the [Timeline], /// for use when profiling. diff --git a/packages/flutter/test/scheduler/scheduler_test.dart b/packages/flutter/test/scheduler/scheduler_test.dart index 085ea958f8..8fb7abb0f1 100644 --- a/packages/flutter/test/scheduler/scheduler_test.dart +++ b/packages/flutter/test/scheduler/scheduler_test.dart @@ -250,6 +250,31 @@ void main() { warmUpDrawFrame(); expect(scheduler.hasScheduledFrame, isTrue); }); + + test('Can schedule futures to completion', () async { + bool isCompleted = false; + + // `Future` is disallowed in this file due to the import of + // scheduler_tester.dart so annotations cannot be specified. + // ignore: always_specify_types + final result = scheduler.scheduleTask( + () async { + // Yield, so if awaiting `result` did not wait for completion of this + // task, the assertion on `isCompleted` will fail. + await null; + await null; + + isCompleted = true; + return 1; + }, + Priority.idle, + ); + + scheduler.handleEventLoopCallback(); + await result; + + expect(isCompleted, true); + }); } class DummyTimer implements Timer {