The function below first performs a synchronous parison 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);
/
The function below first performs a synchronous parison 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/o5kq8he6/2/
Share Improve this question asked Apr 21, 2015 at 17:42 user1032531user1032531 26.4k75 gold badges245 silver badges416 bronze badges 1- 1 Use callbacks or promises instead of a return value. – Sirko Commented Apr 21, 2015 at 17:44
3 Answers
Reset to default 6Since you are already returning a promise from the ajax call, then from your synchronous parison, 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 mon 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 remendation), 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.