如何将Scala Future返回的Databricks并行笔记本结果存入独立变量
实现思路
你调用Await.result(res, 3600000 seconds)时会直接返回Seq[String]类型的纯结果集合,不需要从res.value封装的Option[Try[_]]类型里做两层拆包取值。
Scala的Future.sequence返回的结果顺序,和你传入parallelNotebooks方法的notebooks序列顺序严格一致,不会因为并发执行的先后顺序打乱:第一个元素对应/notebook1的返回值,第二个对应/notebook2,以此类推,可以直接拆分赋值。
具体实现方式
方式1:模式匹配解构(固定4个笔记本场景推荐)
固定笔记本数量时,直接用Scala集合的提取器做解构赋值,写法最简洁:
// 阻塞等待所有笔记本执行完成,拿到顺序一致的结果序列 val notebookResults: Seq[String] = Await.result(res, 3600000 seconds) // 按顺序解构为独立变量 val Seq(res1, res2, res3, res4) = notebookResults // 后续直接调用变量即可: // res1 对应 /notebook1 的返回值 // res2 对应 /notebook2 的返回值 // res3 对应 /notebook3 的返回值 // res4 对应 /notebook4 的返回值
注意:如果后续调整了传入的笔记本总数,解构时元素数量不匹配会直接抛出异常,仅适合笔记本数量固定的场景。
方式2:按索引取值(笔记本数量动态变化场景推荐)
如果后续笔记本数量可能调整,可以通过索引直接取对应位置的结果:
val notebookResults: Seq[String] = Await.result(res, 3600000 seconds) // Scala集合索引从0开始,和传入顺序一一对应 val res1 = notebookResults(0) val res2 = notebookResults(1) val res3 = notebookResults(2) val res4 = notebookResults(3)
方式3:路径映射取值(避免顺序混淆场景推荐)
如果担心记混顺序,可以先把笔记本路径和返回值绑定为Map,后续按路径取值,完全不需要关心执行和返回顺序:
val notebookResults: Seq[String] = Await.result(res, 3600000 seconds) // 构造路径 -> 返回值的映射Map val resultMap: Map[String, String] = notebooks.map(_.path).zip(notebookResults).toMap // 直接按笔记本路径取对应结果 val res1 = resultMap("/notebook1") val res2 = resultMap("/notebook2") val res3 = resultMap("/notebook3") val res4 = resultMap("/notebook4")
注意事项
- 不建议直接从
res.value取结果:这个API返回的是Future执行状态的快照,如果Future未执行完成会返回None,即使执行完成也需要额外拆两层包装,直接用Await.result拿结果是最稳妥的方式。- 你当前的实现已经对单个笔记本的执行异常做了捕获,若返回值以
ERROR:开头,代表对应位置的笔记本执行失败,可以直接在后续业务逻辑中做判断处理。- 当前拿到的返回值都是字符串类型,如果业务需要整数、布尔值等其他类型,在赋值时直接做类型转换即可。
内容的提问来源于stack exchange,提问作者venkat
相关产品推荐
相关产品推荐

