scala callback hell

用户头像
HackMSF
关注
发布于: 2020 年 06 月 07 日
scala callback hell

scala具有异步的编程范式,既然是异步编程,就一定要了解scala中怎么解决callback hell问题。事实上不需要第三方工具,它自己的语法糖for comprehension就能写出易读的代码。



scala中的callback hell大概长这样:

a.map { b =>
b.map { c =>
c.map { d =>
d.map { res =>
res + 10
}
}
}
}

之所以会形成callback hell是因为,在异步编程中,难免有一些动作是有先后顺序的,否则全都并行执行,就不会有这个问题。



使用语法糖for comprehension后的代码大概长这样:

for{
b <- a
c <- b
d <- c
res <- d
} yield res + 10

嗯,这样的代码就容易理解多了,但它只是一个语法糖,编译过后任然是类似上面的callback hell。



到此为止还没完,实际工作中还有个很常见的场景,就是这个过程中,会有一些判断,如果不符合判断就跳出,下面的代码就没必要执行了,比如像这样:

for{
b <- a
if b != 1 //如果b != 1我就希望跳出,下面的代码不需要执行
c <- b
d <- c
res <- d
} yield res + 10

由于b,c,d都是临时占位符(Future),此时数据都还没有真正拿到,所以这里的if判断这样写是会出错的。



可以这样解决:


def findByxxx() {
def predicate(condition: Boolean)(fail: Exception): Future[Unit] =
if (condition) Future(()) else Future.failed(fail)

val f2 = for {
i <- f1
_ <- predicate( i == 2 )(new Exception("Test2")) //如果为predicate为false就会返回异常
j <- f3 // 只有当predicate是true的时候,这行代码才会执行
} yield "Test1"
}

在web开发中,如果findByxxx是service层的方法,那么controller层可以捕获该异常,并做一下对用户友好的封装或转换就ok了。



题图:慕士塔格峰

发布于: 2020 年 06 月 07 日 阅读数: 35
用户头像

HackMSF

关注

prison breaker. 2019.10.12 加入

还未添加个人简介

评论 (1 条评论)

发布
用户头像
@infoQ,为什么代码块中,没有Scala语言的选项?
2020 年 06 月 07 日 23:10
回复
没有更多了
scala callback hell