Block data is written (appended to) blk*.dat files whenever a block is received from the network (assuming things like PoW and a few other sanity checks pass). As blocks are received in parallel from multiple peers, their order on disk ends up being chaotic.
Undo data is written when a block gets fully validated. As full validation requires validation of all parent blocks first, the order of undo records tends to be much more monotonic. However, it is not guaranteed to be be perfectly continuous either, as reorganizations can cause discrepancies. If a received block never ends up being part of the active chain, it will never have an undo record, despite the block data being present.
The only guarantee is that block data and undo data is stored in matching files (e.g. a block which is stored in blk00473.dat will have its undo data in rev00473.dat).