Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dart: How to return Future<void>

How can I return Future<void> ?

   Future<void> deleteAll(List stuff){
       stuff.forEach( s => delete(s));   //How do I return Future<void> when loop and all delete Operation are finished?
   }

   Future<void> delete(Stuff s) async {
      ....
      file.writeAsString(jsonEncode(...));
   }

How do I return Future<void> when the forEach loop and all delete Operations are finished?

like image 437
Frederik Avatar asked Jan 31 '20 09:01

Frederik


2 Answers

You don't need to return anything manually, since an async function will only return when the function is actually done, but it depends on how/if you wait for invocations you do in this function.

Looking at your examples you are missing the async keyword, which means you need to write the following instead:

Future<void> deleteAll(List stuff) async {
    stuff.forEach( s => delete(s));
}

Future<void> delete(Stuff s) async {
   ....
   await file.writeAsString(jsonEncode(...));
}

When using Future<void> there is no need to explicitly return anything, since void is nothing, as the name implies.

Also make sure you call deleteAll and writeAsString() using await.

Note: To wait for all delete/foreach invocations to complete, see below answer for more details. In short you will need to put all delete invocations in a Future.wait for that.

like image 82
gi097 Avatar answered Oct 20 '22 08:10

gi097


You can't do that with forEach.

But you can use Future.wait and .map like this

Future<void> deleteAll(List stuff) {
  return Future.wait(stuff.map((s) => delete(s)));
}

Future<void> delete(Stuff s) async{
  ....
  await file.writeAsString(jsonEncode(...));
}

When to use async keyword:

You can use async when your function uses await keyword inside.

So when to use await keyword:

  1. when you want to get the result from an asynchronous function and want do some logic on the result
Future<int> fetchCountAndValidate() asycn{
  final result = await fetchCountFromServer();
  if(result == null)
    return 0;
  else
   return result;
}
  1. When you want to call multiple asynchronous function
Future<int> fetchTotalCount() asycn{
  final result1 = await fetchCount1FromServer();
  final result2 = await fetchCount2FromServer();
  return result1 + result2;
}

When you don't need async or await:

  1. When you just calling another asynchronous function
Future<int> getCount(){
  //some synchronous logic
  final requestBody = {
    "countFor": "..."
  };
  return fetchCountFromServer(requestBody); //this is an asynchronous function which returns `Future<int>`
}
  1. For some rare cases we doesn't care about the completion of asynchronous function
void sendLogoutSignal(){
  http.post(url, {"username" : "id0001"});
}
like image 39
Crazy Lazy Cat Avatar answered Oct 20 '22 10:10

Crazy Lazy Cat