Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Invoking async function without await in Dart, like starting a thread

I have two functions

callee() async {
  // do something that takes some time
} 

caller () async {
  await callee();
}

In this scenario, caller() waits till callee() finishes. I don't want that. I want caller() to complete right after invoking callee(). callee() can complete whenever in the future, I don't care. I just want to start it just like a thread and then forget about it.

Is this possible?

like image 840
Gazihan Alankus Avatar asked May 31 '16 17:05

Gazihan Alankus


People also ask

Can we use async without await in flutter?

Rule: no-async-without-awaitFunctions marked async must contain an await or return statement.

Can you use async without await?

In this way, an async function without an await expression will run synchronously. If there is an await expression inside the function body, however, the async function will always complete asynchronously. Code after each await expression can be thought of as existing in a .then callback.

What happens when you call async method without await?

The call to the async method starts an asynchronous task. However, because no Await operator is applied, the program continues without waiting for the task to complete. In most cases, that behavior isn't expected.

Does async start new thread?

The async and await keywords don't cause additional threads to be created. Async methods don't require multithreading because an async method doesn't run on its own thread. The method runs on the current synchronization context and uses time on the thread only when the method is active.


2 Answers

When you call the callee function, it returns a Future. The await then waits for that future to complete. If you don't await the future, it will eventually complete anyway, but your caller function won't be blocked on waiting for that. So, you can just do:

caller() {
  callee();  // Ignore returned Future (at your own peril).
}

If you do that, you should be aware of what happens if callee fails with an error. That would make the returned future complete with that error, and if you don't listen on the future, that error is considered "uncaught". Uncaught errors are handled by the current Zone and the default behavior is to act like a top-level uncaught error which may kill your isolate.

So, remember to handle the error.

If callee can't fail, great, you're done (unless it fails anyway, then you'll have fun debugging that).

Actually, because of the risk of just forgetting to await a future, the highly reocmmended unawaited_futures lint requires that you don't just ignore a returned future, and instead wants you to do unawaited(callee()); to signal that it's deliberate. (The unawaited function can be imported from package:meta and will be available from the dart:async library in SDK version 2.14). The unawaited function doesn't handle errors though, so if you can have errors, you should do something more.

You can handle the error locally:

caller() { 
  callee().catchError((e, s) { 
    logErrorSomehow(e, s); 
  }); 
}

(Since null safety, this code only works if the callee() future has a nullable value type. From Dart 2.14, you'll be able to use callee().ignore() instead, until then you can do callee().then((_) => null, onError: (e, s) => logErrorSomehow(e, s)); instead.)

or you can install an error handling zone and run your code in that:

runZoned(() {
  myProgram();
}, onError: logErrorSomehow);

See the runZoned function and it's onError parameter.

like image 164
lrn Avatar answered Oct 19 '22 22:10

lrn


Sure, just omit await. This way callee() is called immediately and when an async operation is called the call will be scheduled in the event queue for later execution and caller() is continued immediately afterwards.

This isn't like a thread though. As mentioned processing is enqueued to the event queue which means it won't be executed until the current task and all previously enqueued tasks are completed.

If you want real parallel execution you need to utilize isolates.

See also

  • https://www.dartlang.org/articles/event-loop/
  • https://api.dartlang.org/stable/1.16.1/dart-isolate/dart-isolate-library.html
  • https://pub.dartlang.org/packages/isolate
like image 45
Günter Zöchbauer Avatar answered Oct 19 '22 23:10

Günter Zöchbauer