Reputation: 39095
Is it possible to invoke async function in flutter sync function without add the async keyword to parent function? I want to invoke the async function like this:
void getEventsForDay(DateTime day) {
var result = await TaskProvider.getTasksByRangeDate(monthStartMilliseconds, monthEndMilliseconds);
}
I could not add async
keywords in the function getEventsForDay
because the outer component did not allow. But I still need to wait the getTasksByRangeDate
return to load some initial data. what should I do to invoke an async function without add async keywords in parent function? BTW, this is the full code:
List<TodoTask> getEventsForDay(DateTime day) {
int monthStartMilliseconds = DateTimeUtils.startOfMonthMilliseconds(DateTime.now());
int monthEndMilliseconds = DateTimeUtils.endOfMonthMilliseconds(DateTime.now());
var result = await TaskProvider.getTasksByRangeDate(monthStartMilliseconds, monthEndMilliseconds);
tasks.addAll(result);
buildHashMap(result);
final DateFormat formatter = DateFormat('yyyy-MM-dd');
String dateString = formatter.format(day);
List<TodoTask> dayTodoTask = taskMap[dateString] ?? [];
return dayTodoTask;
}
I have already tried using then like this:
List<TodoTask> getEventsForDay(DateTime day) {
int monthStartMilliseconds = DateTimeUtils.startOfMonthMilliseconds(DateTime.now());
int monthEndMilliseconds = DateTimeUtils.endOfMonthMilliseconds(DateTime.now());
TaskProvider.getTasksByRangeDate(monthStartMilliseconds, monthEndMilliseconds).then((value) => {getTasks(value, day)});
}
List<TodoTask> getTasks(List<TodoTask> tasks, DateTime day) {
tasks.addAll(tasks);
buildHashMap(tasks);
final DateFormat formatter = DateFormat('yyyy-MM-dd');
String dateString = formatter.format(day);
List<TodoTask> dayTodoTask = taskMap[dateString] ?? [];
return dayTodoTask;
}
seems could not return the task list to outer layer funciton. I have tried like this:
List<TodoTask> getEventsForDay(DateTime day) {
var taskResult;
int monthStartMilliseconds = DateTimeUtils.startOfMonthMilliseconds(DateTime.now());
int monthEndMilliseconds = DateTimeUtils.endOfMonthMilliseconds(DateTime.now());
TaskProvider.getTasksByRangeDate(monthStartMilliseconds, monthEndMilliseconds)
.then((value) => {() => taskResult = getTasks(value, day)});
return taskResult ?? [];
}
List<TodoTask> getTasks(List<TodoTask> tasks, DateTime day) {
tasks.addAll(tasks);
buildHashMap(tasks);
final DateFormat formatter = DateFormat('yyyy-MM-dd');
String dateString = formatter.format(day);
List<TodoTask> dayTodoTask = taskMap[dateString] ?? [];
return dayTodoTask;
}
but the taskResult
result always be Null.
Upvotes: 3
Views: 5505
Reputation: 2526
Yes, it is possible to call async code from a synchronous function !
It will just be executed on another thread.
What we usually do is create an async function and call it from the synchronous one :
import 'dart:async';
void main() {
doSomething();
print('Hello');
}
Future doSomething() async {
await Future.delayed(const Duration(seconds: 2))
.then((_) => print("Oops I am late"));
}
import 'dart:async';
void main() {
unawaited(() async {
await Future.delayed(const Duration(seconds: 2))
.then((_) => print("Oops I am late"));
}.call());
print('Hello');
}
PS : If you don't want to call unawaited()
, you can just remove it, but it is not recommended. After you remove it, it would just look like this :
() async {
// Do something asyncrhronous
}.call();
Try the code on the DartPad !
You can see that we don't use async
in the method main()
for both cases.
I will let you choose which one you prefer. I personally use the Method 2 for debugging purposes.
Upvotes: 4
Reputation: 71873
You cannot.
A function always returns "synchronously" when it's called.
An async
function does too, it just returns a Future
which will complete at some later point.
The point of an asynchronous function is that it doesn't have a result to return immediately.
So, when your synchronous function calls an asynchronous function, and wants to return the result of that, it cannot. The result does not exist yet, at the time where you want to return it.
You must wait for the asynchronous function's future to complete in order to get the result. That means returning from the synchronous function, back to the event loop, so that other parts of the asynchronous computation gets to run.
TL;DR: If your function depends on an asynchronous function's result, your function must also be asynchronous. Anything else does not even make sense, it requires return a result before it event exists.
Upvotes: 4