Many I/O devices, especially historically, had bus timing entirely controlled by transitions on chip-select and read/write lines. Even devices like UARTs which need to have clocks for various purposes would often have bus timing which was independent of that clock, thus allowing them to be used on a wide range of CPUs with different clocking systems.
The biggest difficulty with this approach is something called metastability, which wasn't thoroughly understood in the 1980s. If a device on the bus initiates a read of UART's status almost the precise moment an incoming byte is completed, it would be equally acceptable for the device to report a zero in the "is data ready" bit [the data wasn't ready when the request was received] or a one [the data arrived just in time to be detected].
Unfortunately, there's a third possibility: the device might drive the data bus with a logic level somewhere between a high and low signal, or might start to drive it with a low level and switch to a high level sometime in the middle of a cycle. While a CPU might regard that situation as equivalent to either outputting zero or outputting 1, it might also end up in a weird state, especially if different parts of the CPU grab the signal at slightly different times. Many products in the 1980s didn't pay much attention to such issues, and would have occasional weird failures as a result.
The normal way to prevent problems like this is to use a device called a "double synchronizer". This will ensure that an input transition that occurs near a clock edge will end up being regarded as having been either before it or after it, but at the expense of not being able to say what the signal level currently is--merely what it used to be two cycles ago.
Unfortunately, trying to use a double-synchronizer in a UART without requiring the use of a bus clock would require doing that some bus-initiated action occur before a cycle that's supposed to report UART status, and have the latter action report what the status was when the former action occurred. For example, one could specify that each read of the status register reports the value it had at the previous read request, so code wanting current data would need to read the register twice consecutively. I don't think I've ever seen a UART actually work that way.
The other possibility is to require the use of a bus clock. If serial transmission and reception use a different clock, a double synchronizer would still be necessary, but delaying data-readiness indications by two bus clocks is likely to be less irksome than requiring the use of two separate read events to capture it.