Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do make jquery .each loop wait for response?

How do I make an iteration in a .each loop wait when I call a second function that calls a script in AWS and is waiting for a response from AWS?
This is my .each loop:

$('.subscriptionStatus').each(function(i, obj) {
    var sku = $(this).attr('data-sku');
    subscriptionStatus(sku, function(response) {
        var messageDiv = $(this).closest('.subscriptionMessage');

        var innerHtml = '';
        if (response){
            innerHtml = 'Successful';
        }else{
            innerHtml = 'Failed';
        }
        messageDiv.html(innerHtml);
    }//wait until 
}

for each iteration I'm calling a function, inside i'm calling a script in AWS Lambda and need to wait for its response and then continue the iteration:

function subscriptionStatus( sku, callback ){
    var lambda = new AWS.Lambda();
    lambda.invoke({
        FunctionName: 'MyFunction',
        Payload: JSON.stringify({
            "sku":sku
        })
    }, function(err, data){
        //response from AWS Lambda

        var success = data.Payload;
        if( success == 'true'){
            //NEED TO PASS TRUE BACK TO THE CURRENT ITERATION OF THE EACH LOOP
            callback(true); //correct way?
        }else{
            //NEED TO PASS FALSE BACK TO THE CURRENT ITERATION OF THE EACH LOOP
            callback(false); //correct way?
        }
    });
}

My problem is that the iterations aren't waiting.
What's wrong in my code?

like image 251
MalcolmInTheCenter Avatar asked Mar 08 '26 00:03

MalcolmInTheCenter


1 Answers

The easiest way to do this is with Promises and Deferreds (in jQuery)

what your code would be is roughly:

function subscriptionStatus( sku ){
    var $dfd = jQuery.Deferred();
    var lambda = new AWS.Lambda();
    lambda.invoke({
        FunctionName: 'MyFunction',
        Payload: JSON.stringify({
            "sku":sku
        })
    }, function(err, data){
        if( data.Payload == 'true'){
             $dfd.resolve();
        }else{
            $dfd.reject();
        }
    });
    return $dfd.promise();
}

you can now do:

subscriptionStatus(<sku>)
    .done(function() {

    }).fail(function() {

    });

Now for the fancy part: how to implement this in your .each loop? It depends if it needs to be in the correct order OR if you just have to wait until they are all finished. if you just have to wait for all of them to finish in no particular order:

// no particular order
var deferreds = []; // does nothing yet
$('.bla').each(function(){
    var $this = $(this);
    var $msgDiv = $this.closest('.subscriptionMessage');
    var sku = $this.attr('data-sku');
    var $dfd = subscriptionStatus(sku)
       .done(function() { $msgDiv.html('Successful'); })
       .fail(function() { $msgDiv.html('Failed'); });
    deferreds.push($dfd);
});
jQuery.when.apply(jQuery,deferreds)
    .done(function() { alert('all successful'); })
    .fail(function() { alert('any of the requests was not succesful'); })
    .always(function() { alert('they are all done'); });
like image 102
DoXicK Avatar answered Mar 10 '26 13:03

DoXicK



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!