How to delay command blocks until player respawns?
Solution 1:
Your real problem is that the players can wait arbitrarily long until they click "respawn", so no fixed delay would help you. What you can instead do is detecting when they have respawned. This can for example be done by checking if they are at a location (because dead players are nowhere*):
/execute as @a[scores={deaths=1..},distance=0..] run <command>
This distance=0..
might seem useless, because you're testing for a distance of 0 or more from the command block, but what it does is only activating if you have an alive player in the same dimension. You could also do the same for Nether and End, but since you want to detect respawning, that's not necessary. Dead players have no location, so their distance from the command block isn't 0 or more, it's nothing.
*This got a bit more complicated in 1.15, because the player is still registered as being at their death location for about a second after dying. That could be very helpful in some cases, I think it even used it in an answer here already, but it complicates this case. Now you need to check if they are not at any location first and then at a location again:
execute as @a[tag=!dead,scores={deaths=1..}] unless entity @a[scores={deaths=1},distance=0..] run tag @s add dead
execute as @a[tag=dead,distance=0..] run <command>
execute as @a[tag=dead,distance=0..] run scoreboard players set @s deaths 0
execute as @a[tag=dead,distance=0..] run tag @s remove dead
The first command is the real magic: Every player who died gets tagged, but only once no player who died can be found at any location anymore. This still fails if another player is currently in its death animation, I don't think this can be avoided.
Then you just run whatever command you want at a player that used to be at no location, but is at some location now. Finally, you reset the scoreboard (implied in my 1.14 solution) and the tag.
Solution 2:
Can you use repeaters? If you can, have one command block that detects the player's death and then have a few redstone repeaters lined up to delay the signal to the block that gives the effect.
Solution 3:
Target a player who died only once they've respawned by using the @e target selector instead of @a or @p and specifying [type = player] along with any other selector arguments you're using to pick the correct player (probably a tag or scoreboard value). This works because @a targets any player while @e only targets alive entities as of 1.18.1 Java Edition. So, to solve your problem, you'd do something like execute as @e[type = player, tag = dead] run effect give @s weakness 600 1 true
or execute as @e[scores = {deaths=1..}] run effect give @s weakness 600 1 true
. Note that if you're using a scoreboard, specifying the type is redundant because only players can have scores.