I believe you only see the final result after f[] has fully evaluated because the "MouseClicked" event is using preemptive evaluation, which basically disallows the interrupting dynamic update you were expecting when y = 2 is evaluated.
You can use the Method option on some objects to set their evaluation type. The choice is generally (and I think always, to the best of my knowledge) either "Preemptive" or "Queued". There are a few details about these evaluation methods at
ref/Button:
With the default setting Method -> "Preemptive", button actions are performed immediately, preempting any other evaluation, but are allocated only a limited time to complete.
With the setting Method -> "Queued", button actions are added to the current queue of evaluations, and are performed when other evaluations are complete. No time limit is applied.
With "Queued", an update of y during the action evaluation would trigger an update of visible dynamic objects depending on y. With "Preemptive", the action evaluation finishes before dynamic updates can occur.
For a quick demo, evaluate these three inputs and try the buttons. Watch the value of y shown by the Dynamic:
Dynamic@y
y = 1; Button["testing preemptive", y = 2; Pause@2; y = 3]
y = 1; Button["testing queued", y = 2; Pause@2; y = 3,
Method -> "Queued"]
If you're really interested and have already read the two essential Dynamic tutorials (
Intro and
Advanced), there are some interesting notes on the underlying dynamic mechanism
here: http://reference.wolfram.com/mathematica/tutorial/SomeNotesOnInternalImplementation.html#473534038
I don't know if there is a way to force the "MouseClicked" event callback to use non-preemptive evaluation (if my guess about the cause of this behavior is in fact correct).