How to call an asynchronous JavaScript function and block the original caller

spawn a webworker thread to do the async operation for you. pass it info it needs to do the task plus a unique id. the trick is to have it send the result to a webserver when it finishes.

meanwhile...the function which spawned the webworker sends an ajax request to the same webserver use the synchronous flag of the xmlhttprequest object(yes, it has a synchronous option). since it will block until the http request is complete, you can just have your webserver script poll the database for updates or whatever until the result has been sent to it.

ugly, i know. but it would block without hogging cpu :D

basically

function get(...) {
    spawnWebworker(...);
    var xhr = sendSynchronousXHR(...);
    return xhr.responseTEXT;
}

No, you can't block until the asynch call finishes. It's that simple.

It sounds like you may already know this, but if you want to use asynchronous ajax calls, then you have to restructure the way your code is used. You cannot just have a .get() method that makes an asynchronous ajax call, blocks until it's complete and returns the result. The design pattern most commonly used in these cases (look at all of Google's javascript APIs that do networking, for example) is to have the caller pass you a completion function. The call to .get() will start the asynchronous operation and then return immediately. When the operation completes, the completion function will be called. The caller must structure their code accordingly.

You simply cannot write straight, sequential procedural javascript code when using asynchronous networking like:

var result = abc.get()
document.write(result);

The most common design pattern is like this:

abc.get(function(result) {
    document.write(result);
});

If your problem is several calling layers deep, then callbacks can be passed along to different levels and invoked when needed.


FYI, newer browsers support the concept of promises which can then be used with async and await to write code that might look like this:

async function someFunc() {
    let result = await abc.get()
    document.write(result);
}

This is still asynchronous. It is still non-blocking. abc.get() must return a promise that resolves to the value result. This code must be inside a function that is declared async and other code outside this function will continue to run (that's what makes this non-blocking). But, you get to write code that "looks" more like blocking code when local to the specific function it's contained within.