So -- the design you've chosen is to have this method run continuously and never terminate until the player is done being burned. You can probably find a way to make this design work using something called the "Method Object Refactoring" but, I wouldn't recommend it
A more traditional way to handle logic like this would be something like this:
func apply_burn() -> void:
func on_BurnTimer_timeout() -> void:
effect_time -= 1
if effect_time <= 0:
print("THE END") #done.
# apply dmg
You only really need two small pieces of code; one to say, "Start this timer," and the other to say, "Here's what should happen once a second." Godot will handle all of the other things you wrote -- the idea of 'the timer is running' or 'the timer is not running', the idea of waiting a second, the idea of tracking the amount of milliseconds which have elapsed. The state variable you created is also encapsulated within the timer; you can just check if the timer is running. Godot does all of this, you do not need to code it.
With that said, you might be able to have a short-term band-aid fix by just doing something like effect_time += 5, right? Then if it's already in the loop, it'll stay in the loop longer?