Toy Example of callback-based code in Microvium
See the corresponding blog post here.
The main objective here is to write a sendToServer
function that is an example of an operation that hypothetically takes 3 steps to complete: powering on the modem, connecting to the server, and sending the data. In the spirit of writing non-blocking, single-threaded code, this uses callbacks to trigger the next step when the previous completes.
This example is written to run on the Microvium JavaScript engine, so it doesn't use any features that Microvium doesn't support.
The example is not fully comprehensive. For example, it doesn't include error checking or timeouts. It doesn't check if the modem is powered on, but just powers it on each time (it also doesn't power it off). But it's easy to imagine how modem.powerOn()
could be changed to if (alreadyPoweredOn) ...
, etc.
The example code here is structured into 4 layers:
main.mjs
is just an example usage of thesendToServer
function.send-to-server.mjs
is the implementation ofsendToServer
, basically the same as what was shown in the blog post.modem.mjs
implements a JavaScript wrapper around the C host firmware functions that actually control the modem.events.mjs
is an example event system to translate events from the host firmware into callback calls. This is not specific to the modem code but could underly all events (there is no mention of "modem" in event.mjs).
(in this gist I've prefixed the filenames with numbers just to keep them in order of these 4 layers)
The key point to notice in this example is that the implementation of modem.powerOn
(and the other methods) do not block while the modem powers on. Instead, it starts off the process using startModemPowerOn
and then waits for call from the host firmware to say when the modem is on. During this waiting, the VM is idle and the VM call stack is freed.
When the host firmware calls the JS method eventReceivedFromHost('modem-powered-on')
then the VM wakes up, allocates the call stack, and triggers the next thing to be done
eventReceivedFromHost('modem-powered-on')
callspowerOnCallback
powerOnCallback
callsmodem.connectTo
modem.connectTo
calls the host firmware functionstartModemConnectTo
- Then the VM goes idle again until the next event.
The main intention of this example is to communicate how easy it is to write the high-level, single-threaded, non-blocking logic such as that in sendToServer
, compared with doing the same thing in C.