Today we're looking at how input and output operations can be handled on a computer. But because I spend all my days sat at a laptop I will instead use a chicken to explain this process. Because why not?
See our chicken up there ↑, let's call her Gloria. Gloria is hungry and is looking for something to eat. She finds a tasty worm and gobbles it up. Now would Gloria then come to a complete standstill until said worm has worked its way through her little chicken body? Oh no! That could take ages and Gloria has much to do with her day. Maybe laying the odd egg or two, doing some laundry for the little chicks, I don't know? But the point is she just gets on with chicken related things, and later on when her little worm meal has been digested she's all ready to poop it out (come on, surely you'd realised by now this was not going to be a high-brow blog post!).
This is an example of asynchronous input/output (I/O) processing, or non-blocking I/O, as Gloria can do many other things whilst her worm meal is being 'processed'. The alternative approach would be called, unsurprisingly, synchronous I/O, or blocking I/O, which would prohibit Gloria from doing anything at all after chowing down on that tasty worm until it had been fully processed and returned to the grass where it first came from (all be it in a little chicken poop form). This approach might be OK in some situations, but it's not the right thing for Gloria! What if the Colonel turns up at the farm and Gloria needs to hide behind a tree or something? She'd be rooted to the spot whilst her little chicken tummy digests the worm, the Colonel spots an easy picking and before you can say "Bargain Bucket", she's being served up in gravy and enjoyed with a hot butter biscuit.
Chickens and computers have an awful lot in common. Which is something I never imagined myself typing at any time but honestly they do! Just like Gloria and her digestive system, input and output operations on a computer can be really slow, especially when compared to the processing of data. Take for example an I/O device like a hard drive seeking a track to read or write, or something that has to physically move. That request for a particular operation could take ten milliseconds to perform, which doesn't sound like a long time but when compared to the simple switching of an electric current in a one gigahertz processor it's snail pace. In fact, in that time the processor could've performed ten million instruction-processing cycles! That's a lotta worms!
Leaving Gloria behind now and returning fully to the world of computing, let's clarify asynchronous and synchronous I/O in practice. As we know, with asynchronous I/O processing your code continues executing after one element sends a particular message/calls a function/whatever. Whereas with synchronous I/O your code sends a message/calls a function/whatever but then it is blocked until an answer/response/whatever arrives. This could be seconds, minutes, hours, days.......you get the idea!
But you likely want your asynchronous I/O request to perform a certain task after it has received the answer/response/whatever, right? So to do this we can include a callback function which will only execute when the answer/response to the message/request/function/whatever arrives. This could be seconds, minutes, hours, days......
Here we have a button which after it has been clicked will execute the callback function on line 2. The rest of your code can carry on and do what it wants to do, but after you click that button the callback function will come into play.
Now, anyone fancy KFC?