Scala中Future链式调用问题:确保f2在f1完成后启动
Let's break down your questions clearly—this is a super common gotcha when working with asynchronous code in Scala!
1. Will f2 potentially finish before f1 in the original code?
Absolutely. Let’s look at your initial snippet again:
val f1 = Future {}; val f2 = Future {}; f1.flatMap(_ => f2)
When you declare f1 and f2 as vals, both Future instances are created immediately and submitted to the execution context (like the default fork-join pool) the second those lines run. They start executing concurrently right away—there’s no built-in dependency between them. The flatMap here only waits for f1 to finish before using f2’s result, but it doesn’t stop f2 from running (and even finishing) early.
2. How to ensure f2 only starts after f1 completes?
The fix hinges on delaying the creation of f2 until f1 has finished. Instead of initializing f2 upfront, we need to wrap it in a construct that only runs once f1 is done.
The simplest way is to define f2’s work directly inside the flatMap:
val f1 = Future { /* f1's work */ } f1.flatMap(_ => Future { /* f2's work—only starts after f1 finishes */ })
Here, the inner Future (your original f2) isn’t created or submitted to the execution context until f1 successfully completes.
3. Is the def approach viable and idiomatic?
Yes, this works perfectly and aligns with Scala’s asynchronous coding norms. Let’s examine the code:
def f1 = Future {}; def f2 = Future {}; f1.flatMap(_ => f2)
Unlike val, def is lazily evaluated—every time you call f1 or f2, a new Future is created and started. Here’s what happens step-by-step:
- Calling
f1creates and starts the first future immediately. - The
flatMapwaits forf1to complete, then callsf2—which creates and starts the second future only at that moment.
This guarantees f2 doesn’t start executing until f1 is done, which is exactly what you need. Just be careful: if you call f2 elsewhere in your code before f1 finishes, it will start early—so stick to invoking f2 only within the context of f1’s completion (like inside the flatMap).
内容的提问来源于stack exchange,提问作者jhegedus

