0

i have an issue and i need an idea for solve :)

I have 2 call to $.ajax First, is asynch, and during a lot of time (1 minutes for example) Second, is sync (in ajax async: false) and it response fast (5 sec for example)

Second call is in a loop (requests->response->print data, request->response->print data). I need when first finish (success or error), stop second call.

I attach an example code:

var success = false;
$.ajax({
    type: "POST",
    url: urlRest,
    data: {
        data: dataSend
    },
    success: processOK,
    error: processError
});

do {
    $.ajax({
        type: "POST",
        url: urlData,
        data: {
            data: dataSend
        },
        async: false,
        success: function(data, textStatus, jqXHR){
            console.log(data);              
        },
        error: function(data, textStatus, jqXHR){
            console.log("Error");   
        }  
    }); 
} while (!success);

I hope it's clear :)

pk86
  • 41
  • 6
  • 5 seconds for an ajax call is not fast for the browser. Some browser needs to refresh the UI after every 16ms. So your page may end up as "page not responsive" – Abhinav Galodha Jan 27 '17 at 17:30
  • Never loop Ajax. Put the next call in the success or done callback – mplungjan Jan 27 '17 at 17:31
  • what you are asking for is impossible. The first ajax request's callback can't run while the do while loop is running. – Kevin B Jan 27 '17 at 18:40
  • Why can't it run? Browsers can do 4-6 simultaneous http requests http://stackoverflow.com/questions/1060539/parallel-asynchronous-ajax-requests-using-jquery – mplungjan Jan 27 '17 at 21:02

4 Answers4

0

I corrected an issue that would cause some errors, try this out.

let printData = function( input ){

    let config = {
        urlRest: '',
        data: { data: {} },
        loop: false,
        callback: false
    }

    $.each(config,function(k,v){ config[k] = input[k]   });
        config.loop = false;

        $.ajax({
            type: 'POST',
            url: config.urlRest,
            data: config.data,
            success: function( data ){

                // Based on the response if you need to run again change config.loop to true and it will run again
                // you can also alter anything your sending through

                if( config.loop ) printData( config );
                else if( typeof config.callback === 'function' ) callback();
            },
            error: function(){

                // Based on the response if you need to run again change config.loop to true and it will run again
                // you can also alter anything your sending through

                if( config.loop ) printData( config );
                else if( typeof config.callback === 'function' ) callback();

            }       
        });
}

printData({
    urlRest: '', // URL Here
    data: data,  // Data Object
    loop: true,   // Set this to true if you want it to loop
    callback: function(){
        console.log( 'Job Complete' );
    }
})
Lucas Shanley
  • 406
  • 2
  • 8
  • I don't see use of input.loop, it's a mistake? – pk86 Jan 30 '17 at 15:07
  • @pk86 input only relays information to the config object so that you cant just go wild west with sticking in information. The fed in information ONLY uses values that are setup in the config. You don't initially set input.loop however you change config.loop depending on the return value from your ajax function. This way config becomes input when it loops. :-) The general idea is to abstract it to a single function I'm creating a method that should never error because of something being undefined as the config is the only thing that matters in the end. – Lucas Shanley Jan 31 '17 at 16:44
0

You can run async calls in synchronous manner using SynJS:

function ajaxWrapper(ctx, url, data){
    var res={done:false};
    $.ajax({
        type: "POST",
        url: url,
        data: data,
        success: function(result){
            res.data=result;
        },
        error: function(){
            res.error=true;
        },
    }).always(function(){
        res.done = true;
        SynJS.resume(ctx); // <-- tell caller that callback is finished
    });
    return res; // <-- return object that will hold the results
}

// function that is executed in synchronous manner
function myFunc(modules, urlRest, urlData) {
    var success = false;

    var res1 = modules.ajaxWrapper(_synjsContext, urlRest, urlData);
    SynJS.wait(res1.done); // <-- wait for result from callback

    do {
        var res2 = modules.ajaxWrapper(_synjsContext, urlRest, urlData);
        SynJS.wait(res2.done); // <-- wait for result from 2nd callback
    } while (!success);
}
var modules = {ajaxWrapper: ajaxWrapper};
SynJS.run(myFunc,null, modules, "/", {}, function () {
    console.log('done');
});
amaksr
  • 7,555
  • 2
  • 16
  • 17
-1

You can change the success value like this

$.ajax({
    type: "POST",
    url: urlRest,
    data: {
        data: dataSend
    }
}).always(function() {success=true;});

Or you can create a self call function (after the second ajax finish, calls it again) but before the call its checks the success variable like @mplungjan did.

Onaiggac
  • 551
  • 1
  • 6
  • 21
-1

It is never a good idea to loop Ajax. You need to allow the call to return. Here is an example that is NOT using async false

var firstDone = false,tId;
// call long ajax
$.ajax({
    type: "POST",
    url: urlRest,
    data: {
      data: dataSend
    }
  }).done(processOK);
  }).fail(processError)
  }).always(function() {firstDone=true; clearTimeout(tId);}); // stops the other loop
  

// setup function that can be looped
function callAjax() {
  if (firstDone) return;
  $.ajax({
    type: "POST",
    url: urlData,
    data: {
      data: dataSend
    }
  }).done(function(data, textStatus, jqXHR) {
    console.log(data);
  }).fail(function(data, textStatus, jqXHR) {
    console.log("Error");
  }).always(function() {
    tId=setTimeout(callAjax,1000); // give the server time to recover
  });

}
callAjax();
mplungjan
  • 169,008
  • 28
  • 173
  • 236