Is it ever appropriate to hide an async process behind a sync one?

Is it ever appropriate to hide an async process behind a sync one?

So this is something I’d consider posting to StackOverflow, but it feels like it may not be 100% appropriate for SO and as we know, if you ask something not appropriate, you get knocked down pretty quickly. While this is a technical question, it is also an opinion one as well, so I’m not sure. I figure if I’m not sure, I might as well just ask here and not worry about the SO Overlords approving of my question. I approve, and that’s all that matters. ;)

Ok, so let me start with some background. Almost two years ago I created a simple Cordova app that demonstrated writing to a file: Cordova Example: Writing to a file. I won’t repeat all of that code here, but this is the simple utility function I wrote to support a basic logging system.

function writeLog(str) {
    if(!logOb) return;
    var log = str + " [" + (new Date()) + "]\n";
    console.log("going to log "+log);
    logOb.createWriter(function(fileWriter) {
        var blob = new Blob([log], {type:'text/plain'});
        console.log("ok, in theory i worked");
    }, fail);

logOb is a File object made on startup. This method simply takes input, like “Button clicked”, prefixes it with a timestamp and then writes it to the end of a file. Notice, and this is crucial, it has no result. It just does its work and ends. To me, that’s appropriate for a logging system, you don’t really care when it finished.

Until you do…

Back on that earlier post, someone noticed an issue when they did:

writeLog("actionOne fired 00000");
writeLog("actionOne fired AAAAA");
writeLog("actionOne fired BBBBB");

Basically only one or two items were being appended. Looking at the code now, it is pretty obvious why. Since the logic is async, the multiple calls to it firing at the same time mean the file object is being manipulated by multiple calls at the same time, leading to random, unreliable results.

So the fix is easy, right? Add a callback to writeLog or perhaps a Promise (shiny). Then it is the user’s responsibility to ensure they never fire call #2 till call #1 is done. Maybe something like this:

writeLog('msg').then(function() {
}).then(function() {

That’s not too bad, but here’s where my question comes in. What if we made writeLog (and pretend for a moment that I have it in a module) more intelligent so it simple queued up writes? So in other words, if I did N calls, it would simply handle storing the 2-N calls in an array and processing them one by until done. I’d essentially hide the async nature from the caller.

Now everything about me says that smells wrong, but on the other hand, I’m curious. Is there ever a time where you would think this is appropriate? Certainly for a logging system it seems ok. At worse I send 100K calls to it and the app dies before it can finish, but in theory, we could live with that.


Raymond Camden's Picture

About Raymond Camden

Raymond is a developer advocate for Extend by Auth0. He focuses on serverless and enterprise cat demos. If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support.

Lafayette, LA