Search code examples
jquerydeferred

jQuery: inside one function, become aware of completed promise inside another function


Some Context

Despite six hours of reading, including the official documentation, I'm still having trouble wrapping my head around the implementation of promises. (I get the core concept.) Inside a function X, I have Y number of ajax calls. I've been able to determine when all Y ajax calls have been completed (though, I still don't fully grasp how the syntax produces the result).

The Need

However, I still need to make the caller of function X (another function) aware that all Y ajax calls have been completed. Here's a simplified / semi-pseudocode example. (I'm wondering if my previous attempts failed because of a scope issue, but I'm not seeing deferred object passed to functions in the examples I've seen. I decided to keep the example below "clean" instead of showing a particular failed attempt.)

$.fn.SendEmails = function (emailsToSend) {

    var emailSendingPromises = [];

    $.each(emailsToSend, function (i, p) {
        emailSendingPromises.push($.ajax({
            // relevant stuff
        })
        .done( function () {
            console.log('one email done');
        })
        .fail( function () {
            console.log('one email failed');
        }));
    });

    // when all promises have completed 
    $.when.apply($, emailSendingPromises).always(function () {
        console.log('all emails completed');
        // --- MAKE CALLER AWARE ALL EMAILS ARE COMPLETED ---
    });
}


$.fn.AnotherFunction = function () {

    $().SendEmails(emailsToSend);

    // --- BECOME AWARE THAT ALL EMAILS ARE COMPLETED ---

    // do other stuff only when all emails are completed AND some other things happen
}

Thank you very much for assistance! :)


Solution

  • First, try returning your $.when in your SendEmails function. Then, in your AnotherFunction, after you make this call: $().SendEmails(emailsToSend), add a .then():

    $().SendEmails(emailsToSend).then(function() { /* other stuff */});
    

    The .then() will fire only after the returned promise has resolved.