-
Notifications
You must be signed in to change notification settings - Fork 36
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Killed binding fires again #282
Comments
I've analysed this issue thoroughly and I don't think it's as simple as it seems. val p = Property(1)
val s = Property(2)
div(
produceWithNested(p) { (v, nested) =>
div(
nested(produce(s) { v2 =>
println(v -> v2)
div().render
}
)).render
}
).render
CallbackSequencer().sequence {
s.set(4)
p.set(3)
} prints:
In this case, both listeners have to trigger at least once and the sequencer handles duplication case correctly (adding another Please notice: val fired = ListBuffer.empty[String]
val p = Property(1)
val s = SeqProperty(1,2,3)
val combined = s.combine(p)((v1, v2) => v1 -> v2)
combined.listen(s => fired += s.toList.toString())
CallbackSequencer().sequence {
p.set(2)
s.set(Seq(4,5,6))
}
println("results: " + fired.mkString("\n")) only fires once with correct value. The example you've provided doesn't actually trigger "old" listeners, it fires the newly created ones. It seems that we can avoid this by skipping listeners created after queuing altogether. We cannot just copy the list earlier since we need to allow cancelling during callback processing. Please check proposed solution in #283 |
@ddworak I've played a little with this fix and I've got two snippets for you. The first one: val p = Property(2)
val s = Property(3)
div(
produceWithNested(p.transform(_ + 1)) { case (v, nested) =>
div(
nested(produce(s) { v2 =>
println((v, v2))
div().render
})
).render
}
).render
CallbackSequencer().sequence {
p.set(20)
s.set(30)
}
CallbackSequencer().sequence {
s.set(300)
p.set(200)
} It prints:
The second seems to be a bug introduced in #283. You cannot remove these val t = Property(10)
val regs = ArrayBuffer.empty[Registration]
regs += t.listen(_ => { println("1"); regs.foreach(_.cancel()) })
regs += t.listen(_ => { println("2"); regs.foreach(_.cancel()) })
regs += t.listen(_ => { println("3"); regs.foreach(_.cancel()) })
regs += t.listen(_ => { println("4"); regs.foreach(_.cancel()) })
regs += t.listen(_ => { println("5"); regs.foreach(_.cancel()) })
regs += t.listen(_ => { println("6"); regs.foreach(_.cancel()) })
regs += t.listen(_ => { println("7"); regs.foreach(_.cancel()) })
regs += t.listen(_ => { println("8"); regs.foreach(_.cancel()) })
t.touch() It throws an exception: "An undefined behavior was detected: undefined is not an instance of scala.Function1". |
The second is obviously a bug which our test suite didn't cover and I didn't check this case in JS (it works on the JVM due to The first one is a non-issue and I'll have to consider it more thorougly. In the example, the |
Closed in favour of #290 |
Tested on
0.8.0-RC2
.The code above prints:
The last 3 lines are unexpected. It seems
CallbackSequencer
keeps the listener fromSeqPropertyModifierUtils:108
and thehandlePatch
method does not check if the binding was already killed.The text was updated successfully, but these errors were encountered: