简体   繁体   中英

Return value from asynchronous OR synchronous JavaScript request

The function below first performs a synchronous comparison test == 0 , and if it passes, returns some content, and if it doesn't pass, performs an asynchronous request. My intent is for the later to return some other content such as "something from post callback", but know I am doing things way wrong. Without changing the Ajax request to synchronous, is it possible to do this?

var value = function (test) {
    if (test == 0) {
        return 'value is zero ';
    } else {
        return $.post('/echo/html/', {
            html: 'false ',
            delay: .5
        }, function (r1) {
            console.log('r1', r1);
            return 'something from post callback';
        })
            .done(function (r2) {
            console.log('r2', r2);
            return 'something from done callback';
        });
    }
}(1);

console.log(value);

https://jsfiddle.net/o5kq8he6/2/

Since you are already returning a promise from the ajax call, then from your synchronous comparison, just return a resolved promise. Then, both code paths return promises that are resolved with the terminal value and the caller can use the same code to process the result no matter which way it works internally. This is a common design pattern for code that is sometimes synchronous and sometimes asynchronous.

var myFunc = function (test) {
    if (test == 0) {
        return $.Deferred().resolve('value is zero ');
    } else {
        return $.post('/echo/html/', {
            html: 'false ',
            delay: .5
        }).then(function (r2) {
            console.log('r2', r2);
            // this will be the return value of the promise
            return 'something from ajax finished';
        });
    }
};

myFunc(1).then(function(value) {
    // value is here either way
});

FYI, it does not make sense in your $.post() to use both a success handler function AND a .done() handler. If you're going to return a promise from the function (which is my recommendation), then you should use only promise handlers, not the success callback.

You may also need to understand that it does nothing useful to return a value from the success handler of an ajax call. That return value just goes back into the asynchronous bowels of the ajax infrastructure and is never used by anything.

Make it all async:

var value = function (test, callback) {
    if (test == 0) {
        callback('value is zero ');
    } else {
        return $.post('/echo/html/', {
            html: 'false ',
            delay: .5
        }, function (r1) {
            console.log('r1', r1);
            callback('something from post callback');
        })
            .done(function (r2) {
            console.log('r2', r2);
            callback('something from done callback');
        });
    }
}(1, function(result) { console.log(result); } );

You can simulate an async call for the others and then use a callback for all:

var value = function (test, callback) {
    if (test == 0) {
        callback('value is zero ');
    } else {
        return $.post('/echo/html/', {
            html: 'false ',
            delay: .5
        }, function (r1) {
            console.log('r1', r1);
            callback('something from post callback');
        })
            .done(function (r2) {
            console.log('r2', r2);
            callback('something from done callback');
        });
    }
}(1, myCallback);


function myCallback(result) {
   // here will the result be
}

You can also use setTimeout to actually make the sync calls behave as async calls in case you should need that.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM