54

I'm interacting with a third-party JavaScript library where some function calls are asynchronous. Instead of working the asynchronous logic into my application, I preferred to write synchronous wrappers to those async calls. I know, I know, it's terrible design, but this is a demo project with very high chance of being rewritten entirely. I need something to show the team the concept, not really having to worry performance, yet.

Here's what I wanna do:

function sync_call(input) {
    var value;

    // Assume the async call always succeed
    async_call(input, function(result) {value = result;} );

    return value;
}

I tried the jQuery's deferred and promise but it seems to be aiming at the async design pattern. I want to use the synchronous pattern in my code.

Code Different
  • 90,614
  • 16
  • 144
  • 163
  • You cannot make a synchronous wrapper for an async task. Use the deferred/promise pattern! – Bergi Sep 10 '13 at 23:29
  • 2
    possible duplicate of [How to return the response from an asynchronous call?](http://stackoverflow.com/questions/14220321/how-to-return-the-response-from-an-asynchronous-call) – Liam Jul 28 '15 at 10:51

3 Answers3

39

This will never work, because the JS VM has moved on from that async_call and returned the value, which you haven't set yet.

Don't try to fight what is natural and built-in the language behaviour. You should use a callback technique or a promise.

function f(input, callback) {
    var value;

    // Assume the async call always succeed
    async_call(input, function(result) { callback(result) };

}

The other option is to use a promise, have a look at Q. This way you return a promise, and then you attach a then listener to it, which is basically the same as a callback. When the promise resolves, the then will trigger.

bitoiu
  • 6,893
  • 5
  • 38
  • 60
  • Alright, didn't realize that. It's doable in C (mutex) and C# (.NET has built-in support). I will rework the whole thing then. My team is most familiar with C# so if I thought if I write code as close to C# as possible, it stands a better chance of being accepted. – Code Different Sep 11 '13 at 11:38
  • 8
    This doesn't look right and is actually very funny because sync_call signature is identical to async_call signature and is completely redundant. If sync_call accepts a callback, then it is no longer synchronous. Where is the value that it returns? It doesn't return a value before it exits. If it is to be synchronous it must return the value when it returns/exits. – Lzh Nov 01 '14 at 04:27
  • I tried to adapt the code from the questions as little as possible. Who names functions `sync` and `async` anyway? The point is that the user is doing an async call with the callback expecting it to resolve in the scope of the original function. My very simple and naive piece of code adds a callback to his original function and stops the processing of the var `value` in the end of the function. – bitoiu Jan 29 '15 at 14:58
  • Do to a lot of criticism for using the same function name as the OP, I decided to change it. – bitoiu Oct 09 '15 at 15:53
1

How about calling a function from within your callback instead of returning a value in sync_call()?

function sync_call(input) {
    var value;

    // Assume the async call always succeed
    async_call(input, function(result) {
        value = result;
        use_value(value);
    } );
}
jbiz
  • 394
  • 1
  • 5
  • 1
    this is not a proper answer, because the callback is not defined in the argument list. – bitoiu Sep 10 '13 at 22:34
  • 1
    It's workable some minor tweaks, but really isn't much different from jQuery's promise pattern. Thanks for answering anyways. – Code Different Sep 12 '13 at 02:28
0

Here is a working example of how:-

function testAsync(){
    return new Promise((resolve,reject)=>{
        //here our function should be implemented 
        setTimeout(()=>{
            console.log("Hello from inside the testAsync function");
            resolve();
        ;} , 5000
        );
    });
}

async function callerFun(){
    console.log("Caller");
    await testAsync();
    console.log("After waiting");
}

callerFun();

Outputs:

Caller
Hello from inside the testAsync function
After waiting

To make it more complete, error handling should be added (deal with the reject() case).

See here for other examples: https://www.delftstack.com/howto/javascript/javascript-wait-for-function-to-finish/