Trap expressions don't have to be individual functions or programs, they can be more complex expressions as well.
By combining jobs -p and kill, we can kill all spawned child processes of the shell on exit:
jobs -p
kill
trap 'jobs -p | xargs kill' EXIT