0

i have a function that return a success callback when it's the process succeed and a fail callback when the process failed .

the problem is how to wait the function untill it finished and get the returned value before continue to execute other code .

i tried to use the $.deffered, promise functions that provide jquery but it doesn't seems to work with non-ajax function .

this is how it looks like my function

function process(){
var picture = foo(parameters,callbackOnSuccess,callbackOnFail);
var picture1 = bar(parameters,callbackOnSuccess,callbackOnFail);
// wait untill the values are returned and do some code with picture and picture1 vars ...
}

function callbackOnSuccess(res){
return res.pictureID;
}

function callbackOnFail(error){
return error.message;
}

PS : i can't put my whole code on the CallbackOnSuccess as it's not a solution especially when i have a lot of function that i need to wait for .

Hamzar
  • 83
  • 1
  • 9
  • try `$.when().then();` – guradio Feb 09 '16 at 04:13
  • @guradio could you put an example ? because i tried it but i didn't know how to get the parameters the function send with the callback – Hamzar Feb 09 '16 at 04:15
  • Learn about [Promises](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) – epascarello Feb 09 '16 at 04:43
  • What do `foo()` or `bar()` do? An ajax request? – Joaquín O Feb 09 '16 at 04:45
  • @epascarello it didn't helped me . – Hamzar Feb 09 '16 at 06:40
  • @JoaquínO no its not ajax .. – Hamzar Feb 09 '16 at 06:40
  • So if it is not Ajax, what is it than. What is the asynchronous non Ajax call? – epascarello Feb 09 '16 at 12:00
  • Exact same question. What do you do asynchronously? – Joaquín O Feb 09 '16 at 15:50
  • @epascarello its a function that process some stuffs and when it finishs it return a value using the sucess callback or the failer callback depends on the returned value . – Hamzar Feb 10 '16 at 00:14
  • @JoaquínO see my comment above – Hamzar Feb 10 '16 at 00:14
  • @Hamzar Why would you want to *process some stuff* asynchronously? Almost any *process* you need to run that doesn't envolve an AJAX call will be completed in no time.. Maybe you can even avoid the callback functions.. – Joaquín O Feb 10 '16 at 02:51
  • I mean, if there is no AJAX call, (and timeouts, and some other stuff), JS will natively "wait" for the function to return a value, no need of extra code. – Joaquín O Feb 10 '16 at 02:54
  • @JoaquínO i will use ajax when i get the returned value from the first function (callback) i think you got it now? – Hamzar Feb 10 '16 at 05:20
  • So you need promises, either jQuery's when or then or the native promises I linked too. If it is also asynchronous, you can not return from the callbacks so what you have in your original question is impossible to do. Read http://stackoverflow.com/questions/23667086/why-is-my-variable-unaltered-after-i-modify-it-inside-of-a-function-asynchron – epascarello Feb 10 '16 at 12:03
  • @epascarello this is what i have tried and i didn't got it work : https://jsfiddle.net/fqbvLm17/ – Hamzar Feb 11 '16 at 07:46
  • because you can not return from asynchronous methods, that is the problem. – epascarello Feb 11 '16 at 13:22
  • @Hamzar, just one more question to finally understand: what do foo and bar return? Could you post a minimum example of foo()? Thanks. – Joaquín O Feb 12 '16 at 03:58
  • @JoaquínO well if the foo function done successfully it will return the callbackOnSuccess function if it failed it will return the callbackOnFail callback . – Hamzar Feb 13 '16 at 04:49
  • @Hamzar I think that your problem here is that you aren't sure of what you want, and what asynchronous taks mean. If you have some process (this means do any data transformation) that returns a value, you don't have any async stuff. Maybe this example can help you out: https://jsfiddle.net/jormaechea/z68oyavy/ If it helped you, let me know and I'll post it as an answer ;) – Joaquín O Feb 14 '16 at 21:26

3 Answers3

1

jQuery deferred is the way to go for this. You need to create promise object with $.Deferred and resolve/reject them as per your requirement. I created a fiddle for the same. Hope it will help you :)

https://jsfiddle.net/gnekLssh/1/

If you see in the fiddle all the values are printed first and once the values are printed then the method will go to the success callback. And please dont go to the path of callback hell. We all can do better than that.

 $(document).ready(function() {
function success(data){
 alert('I am inside success');
 alert(data);
}

function failure(data){

 alert('I am inside failure');
 alert(data);
}

function always(){

 alert('I will always be called')
 }

 function demoPromise(){
        $.when(showPromiseSuccessMagic(true)).then(success,failure).always(always);
$.when(showPromiseSuccessMagic(false)).then(success, failure).always(always);


 }


function showPromiseSuccessMagic(isSuccess){
        alert('Inside showPromise');
    var deferred = $.Deferred();

  if(isSuccess){
    setTimeout(function(){
        alert('Starting countdown now');


      for(var counter =0; counter <10; counter ++){
        $("#counter").append(counter);
        alert(counter);
        if(counter == 9){
                alert('Now counter will stop and promise will resolve');
                            deferred.resolve('Resolved value goes here');

        }

      }

   }
   , 2000);
   }else{
      deferred.reject('Rejected Value goes here');
   }



   return deferred.promise();

 }

 function showPromiseFailureMagic(){
  var deferred = $.Deferred();
  deferred.reject('Rejected promise');
  return deferred.promise();

 }

 demoPromise();

});

<div id ="counter"></div>

Hope this be of some help.

Happy Learning

Vatsal

Vatsal
  • 2,068
  • 4
  • 21
  • 24
  • the callback should return only one value either its succeced or failed not both and i have to store this value into variable and complete the other stuffs , could you please rewrite the code? – Hamzar Feb 09 '16 at 06:44
  • i think you didn't see my comment the callback function will only return a value not print or do anything other , so when i use deffered i have to get the value return from the callbackfunction and store it then go inside the other code .. you can copy my code from the question and write it with you method so i can learn withouy any forther code please . – Hamzar Feb 10 '16 at 00:17
  • 1
    All of us here are to learn with examples .. Did you try to do anything by yourself other than the example you pasted yesterday? Please paste the code you tried so I will try to enhance it – Vatsal Feb 10 '16 at 00:34
-2

You want to process synchronously, not asynchronously. Try using async:false in the jQuery ajax function.

kizeloo
  • 183
  • 8
  • You shouldn't use synchronous requests. They freeze the browser until the request finishes. From Mozilla MDN, `synchronous requests on the main thread have been deprecated due to the negative effects to the user experience.` – Joaquín O Feb 09 '16 at 04:43
  • @Joaquín O. So you're saying the timeout setting doesn't work for the $.ajax function? You could even check it yourself by setting a timer on the window to check it and kill it if necessary. – kizeloo Feb 09 '16 at 04:47
  • I'm saying that in 99.99% of cases, it's a really bad idea to use synchronous ajax requests. And this is one of those. During a synch ajax req, you cannot click, scroll, or do any interaction with the site. Imagine this in mobile: 5 seconds of frozen phone. In case you abort after a few seconds, imagine your phone frozen and then it fails. You can't argue against that. – Joaquín O Feb 09 '16 at 04:52
  • Nor Mozilla, nor Google deprecated the synchronous ajax without a good reason. – Joaquín O Feb 09 '16 at 04:53
  • The OP asked a question because he wants to do it. I'm not asking why or tormenting him about the reasons why not to. He asked a question, and I answered it. Case closed. – kizeloo Feb 09 '16 at 05:07
  • If you want to move a chair and I encourage you to hit it with a truck, it's an answer, and you'll move the chair, but it's not a GOOD answer actually. You're not helping the OP giving him/her a bad practice.. – Joaquín O Feb 09 '16 at 05:14
  • This is a Q&A site, it's not for mentoring. – kizeloo Feb 09 '16 at 05:35
  • i said its not an ajax request please read the post carefully . – Hamzar Feb 09 '16 at 06:44
  • @kizeloo Your comment out a timeout is incorrect, you can not set a timeout to kill a synchronous request. – epascarello Feb 10 '16 at 11:59
-2

make the call synchronous. Code will wait for the response

var request = new XMLHttpRequest();
request.open('GET', '/bar/foo.txt', false);  // `false` makes the request synchronous
request.send(null);

if (request.status === 200) {
 console.log(request.responseText);
}

Source: https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Synchronous_and_Asynchronous_Requests

user9480
  • 324
  • 1
  • 13
  • Don't ever go synchronous. A little kitten dies every time you do it. – Joaquín O Feb 09 '16 at 04:36
  • Now seriously, the even the docs you linked agree with me: `synchronous requests on the main thread have been deprecated due to the negative effects to the user experience.` – Joaquín O Feb 09 '16 at 04:40
  • @Joaquín O. Whoever wrote that didn't think the whole thing through then. You could easily set a timer to kill the request if it takes too long. Heck, there's even a timeout setting for the $.ajax function. – kizeloo Feb 09 '16 at 04:45
  • Why in hell would you kill your own request (that you obviously need to be done) when you could get it running in background??? What you're trying to say is that the two most important browsers don't think things through before deprecating a functionality? I couldn't disagree more with you. – Joaquín O Feb 09 '16 at 04:57
  • I'm saying there are sometimes you would want to use it. They put it in the browser in the first place. – kizeloo Feb 09 '16 at 05:04
  • i said its not an ajax request please read the post carefully . – Hamzar Feb 09 '16 at 06:44