Oh, the differences in what trap -p is printing is because of special case handling for trap in a subshell environment, when the trap command is the first (maybe only) command executed (details vary between shells). That is mostly intended to allow T=$(trap -p) to work, but is usually applied to any subsell environment (it is simpler that way). An async command is a subshell environment.
When you do foofunc& the trap command thus prints the trap from the parent's environment, but when you embed that ina group, the traps get reset to those for the subshell before the trap command gets to run, so you see that instead. Everything is working as intended. kre