web/laminar
EventStream 의 flatMap vs combineWithFn
wefree
2022. 10. 1. 17:37
코드
package com.github.windbird.playweb
import com.raquo.laminar.api.L._
import org.scalajs.dom
object Main {
def main(args: Array[String]): Unit = {
val buttonA = button("A")
val buttonAE = buttonA.events(onClick.mapTo(scala.math.random())).debugLog()
val buttonB = button("B")
val buttonBE = buttonB.events(onClick.mapTo(scala.math.random())).debugLog()
// val c: EventStream[String] = buttonAE.combineWithFn(buttonBE)((x, y) => s"$x + $y")
val c: EventStream[String] = for {
x <- buttonAE
y <- buttonBE
} yield s"$x + $y"
val content = div(
buttonA,
buttonB,
br(),
label("response: "),
child.text <-- c
)
val containerNode = dom.document.getElementById("main_content")
render(containerNode, content)
}
}
설명
- for-comprehension 의 경우 buttonA event 가 있고 난 다음에 buttonB event 가 발생해야 c 값이 emit 된다. 순서도 중요하다. 특히, 첫 클릭으로 buttonB 가 클릭될 경우 아무런 event 도 전달되지 않는다. for-comprehension 을 flatMap 으로 변환해 보면 쉽게 이해된다. (debug 로그에도 안찍힘)
- combineWithFn 의 경우는 buttonA, buttonB 클릭으로 양쪽 모두 적절한 값이 세팅된 상태일 때, 어느 하나만 클릭되어도 c 값이 emit 된다.
보통 기대하는 동작은 combineWithFn 이 될 것 같다.