tezvyn:

Difference between Future<void> and void from an async function

AI-drafted, machine-checkedSource: dart.devbeginner
WHAT IT TESTS

Knowledge that async always produces a Future.

ANSWER OUTLINE

Future<void> lets callers await and catch errors; void hides the Future, preventing await and leaving exceptions uncaught.

RED FLAG

Believing void async returns are awaitable.

WHAT THIS TESTS: This question checks if you understand that the async keyword in Dart implicitly wraps the function body in a Future before returning to the caller. It also tests whether you know that the static return type, Future<void> versus void, determines what the caller is allowed to do with that Future, especially around awaiting completion and handling errors.

A GOOD ANSWER COVERS: First, state that an async function always returns a Future at runtime, even if the declared return type is void. Second, explain that Future<void> gives the caller a handle to the Future, so they can await it to know when the operation finishes and wrap it in try/catch to handle exceptions. Third, explain that void hides the Future from the caller; the work still runs asynchronously, but the caller has no way to await completion and no way to catch errors thrown inside the function, which usually become uncaught async exceptions. Fourth, mention that returning void from an async function is generally an anti-pattern when the caller needs to sequence work or handle failures.

COMMON WRONG ANSWERS: Saying that a void async function runs synchronously. Claiming that the caller can still await a void async function by ignoring the type system. Asserting that exceptions in a void async function will propagate to the caller automatically; they do not, because the caller has no Future to attach an error handler to. Confusing Future<void> with void and thinking the difference is only stylistic.

LIKELY FOLLOW-UPS: When would you intentionally use void instead of Future<void>? The interviewer might ask about fire-and-forget scenarios and how to safely handle errors in them. They might also ask how this interacts with Flutter widget lifecycles, for example awaiting an async cleanup method in dispose. Another follow-up is how zone error handlers or runZonedGuarded interact with uncaught async errors from void async functions.

ONE CONCRETE EXAMPLE: Consider a function that writes to a local cache. If you declare it as Future<void> writeCache() async { await file.writeAsString(data); }, the caller can write await writeCache() and catch any IOException. If you declare it as void writeCache() async { await file.writeAsString(data); }, the caller cannot await it. If the write fails, the resulting exception has no awaiting Future and no try/catch block attached, so it becomes an uncaught async error that may crash the app or only be caught by a zone handler.

Read the original → dart.dev

Get five bites like this every day.

Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.