@bingrunj said:
so... I'm a bit confused about the yield and the signal emit time.

Why do you need the whole yield/signal thing in the second case? Just normally call the function that triggers the shake and let it normally return. If it all happens immediately as is evident from your red and green arrows, why complicate it needlessly?
If you want to understand the problem with your code - follow the flow in the minimal case example:
in foo:
bar.start() #signal fires while we're here, inside bar.start(), too early for following yield to catch it
yield(bar, "STARTED") # entering yield too late, signal already happened, we'll wait in vain
in bar:
func start():
print("STARTED")
emit_signal("STARTED")