The onRequest handler is a real interrupt function and it is called immediately.
The code of Wire.cpp and utility/twi.c work together.
https://github.com/arduino/Arduino/tree/master/hardware/arduino/avr/libraries/Wire/src.
In twi.c is a single large interrupt routine that works almost like a state machine. It calls the onReceive and onRequest functions (via a pointer and via an other function) from that interrupt routine.
You don't need a delay in the Arduino loop(). You can use an empty loop().
However, in your sketch you probably need code in the loop().
Using the Serial functions (or delay or display functions or sensors via I2C) in a interrupt is not good. The Serial functions use interrupts themself, and things can get stuck with blocked interrupts.
Use volatile counters in interrupts, but do calculations and Serial things in the loop().
If you use an Arduino Uno, that is a 8-bit microcontroller. That means that when decay is read in the loop(), an interrupt could occur right in between reading the MSB and LSB of the delay variable.
The Wire.write() writes a byte, as @cattledog mentioned.