0

First, Please correct me anything I inferred about asynchrounous programming in dart, and even what I summarized from the docs, And please check if my idea about when Future objects are correct. I cannot really think of how to experimentally test my ideas.

whats in the docs

  • asynchronous operation
    • doesn't block other code until its done
  • synchronous operation
    • blocks other code until it's done
  • asynchronous function
    • has at least one asynchrnous operation
  • synchronous function
    • has only synchronous operation
  • await can only be used on functions with async keyword
  • async forces the return value be of type Future<T>

what I inferred from experimenting with dart LSP

  • asynchrounous function
    • is an asynchrounous operation when called in dart
      • is only synchronous when called with await, blocking next lines of code.
  • async forces the return value be of type Future<T>
    • with the exception of void
      • it is asynchrounous operation anyways
      • but await can only be called on the function if the return type is Future<void>
  • if a Future is explicitly returned with a return keyword
    • necessary to have a return value of type Future<T> in the function definition
    • doesn't necessarily mean the function has async mark
  • if a future is not returned but there exist an asynchrounous operation in the function body
    • return value can be just void
    • return value can be Future<void> with async mark as well

My Theory on return timing of Future objects

  • I have some ideas on when exactly a Future is returned, based on my understanding of Future objects
  • But I can't write an apt code to test this ideas below
  • assume fast operation takes one second
  • assume slow operation takes 100 seconds
void foo1 (){
  fastAsynchrounousOperation();
  slowSynchronousOperation();
}

void foo2 (){
  slowAsynchrounousOperation();
  fastSynchronousOperation();
}

void foo3 (){
  fastSynchronousOperation();
  slowAsynchrounousOperation();
}

void foo4 (){
  slowSynchronousOperation();
  fastAsynchrounousOperation();
}

Future<void> foo1 () async{
  fastAsynchrounousOperation();
  slowSynchronousOperation();
}

Future<void> foo2 () async{
  slowAsynchrounousOperation();
  fastSynchronousOperation();
}

Future<void> foo3 () async{
  fastSynchronousOperation();
  slowAsynchrounousOperation();
}

Future<void> foo4 () async{
  slowSynchronousOperation();
  fastAsynchrounousOperation();
}

  • the above functions are valid, and when called, becomes asynchrounous operation. doesn't block anything.
Future<String> foo5 () async {
  fastAsynchrounousOperation();
  return slowSynchronousOperation();
}
  • A completed future is returned only after 100 seconds. Uncompleted Future cannot be returned
  • In other words, Future object either uncompleted/completed is only returned after the synchronous part of a function body is finished.
Future<String> foo6 () async {
  slowAsynchrounousOperation();
  return fastSynchronousOperation();
}
  • A uncompleted future is returned after after 1 second(not right after the execution)
  • future gets complete after 100 seconds
Future<String> foo7() async {
  fastSynchrounousOperation();
  return slowAsynchronousOperation();
}
  • A uncompleted future is returned after 1 second
  • future gets coplete after 101 seconds
Future<String> foo8 () async {
  slowSynchrounousOperation();
  return fastAsynchronousOperation();
}
  • A uncompleted future is returned after 100 second
  • future gets complete after 101 seconds
2
  • A thing to note about Dart, asynchronous functions will behave as though they are synchronous until the first await is encountered, which means that if you have an async function that never awaits anything, it's effectively a synchronous function. This means that in all of your example functions, all of them will "return" uncompleted futures and then complete synchronously with the futures not completing until the event thread is no longer blocked by the synchronous tasks. Commented Sep 11 at 20:04
  • You could use: Future.delayed to experiment and validate your assumptions. Commented Sep 13 at 12:03

1 Answer 1

0

In your statement: "is only synchronous when called with await, blocking next lines of code.", as far as I know, it depends on the process within the function. It behaves synchronously only if you call a Future<T> function without awaiting it, for example:

Future<void> SomeFutureFunction() async {
  await SomeVoidFutureFunction();
}

void main() { // for demonstration purposes only.
  SomeFutureFunction();
}

However, in your UI, it depends on how you handle your process (e.g., providing a loading interface or other related feedback to inform the user that the data is not yet completely loaded). Specifying async in the Future<void> is necessary when you need to ensure that the nested asynchronous function is handled asynchronously, for example:

Future<void> SomeFutureFunction() async {
  await SomeVoidFutureFunction();
}

Future<String?> SomeAnotherFutureFunction() async {
  return await SomeNullableStringFutureFunction();
}

// and so forth...

The concept of synchronous and asynchronous functions allows your application to behave differently depending on the function type you use. For example, if you have heavy tasks to complete and you don't want to block user interaction or other processes, use asynchronous operations. But if you want a certain function to interrupt or halt a process, use a synchronous function.


If you mixed them up, it depends on how you manage them within your hierarchical process, especially if you simulate the delay before proceeding to another method.


The speed of the process usually depends on the device specification, internet speed, and code optimization. So, it is generally recommended to handle time-consuming or large amounts of data with asynchronous operations.


However, if you're concerned about the strange behavior of your functions, try inspecting the code to see what's causing a bottleneck during the process. Moreover, note that the meaning of Future<T> is that it could await a return of any type.


Additional side note, since you described the word "uncompleted", but in Dart:

Uncompleted is a Dart term referring to the state of a future before it has produced a value.


Lastly, avoid simulating delay that introduces overheads to your process, because it would degrade your UX design if you handled it improperly.


Nonetheless, proper usage of synchronous and asynchronous functions is one of the important aspects for your app to offer a user-friendly experience.

Sign up to request clarification or add additional context in comments.

5 Comments

My mistake. I meant "is only synchronous when called with await". Edited. But anyways , do you mean asynchronous functions will behave 'asynchronously'? (I guess what you menat 'it' is asynchronous function.) Because in the first example, SomeFutureFunction() in main will not block any code if there were more lines of code in the main function's body after it. I don't understand why you stated synchronous.
Please rephrase your statement: "do you mean asynchronous functions will behave 'asynchronously'". Do you mean, "will behave 'synchronously'"?
by 'behave asynchronously` i mean does not block next lines of code. So "do you mean asynchronous functions will behave 'asynchronously'" in other words is " do you mean asynchronous functions(functions with at least one asynchronous operation) will not block next lines of code until the execution is complete?"
"by 'behave asynchronously` i mean does not block next lines of code.". It will behave asynchronously if you solely call it with await, and it will not block the next line of code.
"Do you mean asynchronous functions will behave '(a)synchronously'?" Yes, you're correct (if the (a) is removed). When a function is called without await, it behaves synchronously. However, if that function contains nested await calls, it will behave asynchronously at that point. The concept can be a bit confusing, but that's how it truly works. In addition, Abion47's comment on your question is also correct.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.