I have a test case where I want to send a request to the server every time a form field change event occurs.  The implementation below works as expected until I submit the form and check for any empty values (this is the only front-end validation carried out, the rest is done via ajax). If a field is empty I trigger a change event so validation can be carried out on the server side. In the example below I had to set async=>false so each trigger would work as expected.  I realize this is not ideal and there is a better way around this using deferred/promise patterns.I am already using somewhat of the pattern .promise and .then however I think I need to use the .when method but I am unsure how to work it into my partially working example.I am also a little unsure of the amount of request being sent to the server. Is it viable to send this many, i.e.: each time an event occurs?Please ignore the block comments, I just use them for code separation.(function($){var Registration= {};/** *  * @type type**/Registration.fields = {};    /** *  * @type type**/Registration.options = {    cache       : false,    type        : 'POST',    dataType    : 'json',    url         : SITE_URL + '/members/validateFieldOnChange',    context     : undefined,    data        : undefined,    async       : false    // TODO};/** *  * @returns {undefined}**/Registration.init = function(){    //caching    this.Form = $('form#form-register');    this.fields = {        username    : this.Form.find('#username'),        email       : this.Form.find('#email'),        password    : this.Form.find('#password'),    };       // register event handlers    this.Form.on('change', 'input', $.proxy(this.handleEvents, this));    this.Form.on('submit', $.proxy(this.handleEvents, this));};/** *  * @param {type} event * @returns {undefined}**/Registration.handleEvents = function(event){       var type, target     event.preventDefault();    type   = event.type;    target = event.target;    if(type == 'change'){        return this.handleChangeEvent(event.target);    }    return this.handleSubmitEvent();      };/** *  * @param {type} target * @returns {undefined}**/Registration.handleChangeEvent = function(target){    this.options.context = target;    this.options.data = { field : target.name, value : target.value}    return this.validate();};/** *  * @returns {undefined}**/Registration.handleSubmitEvent = function(){    // Ugly testcase if values are empty    // TODO    if($('#username').val() == ''){        $('#username').trigger('change');    }    if($('#email').val() == ''){        $('#email').trigger('change');    }    if($('#password').val() == ''){        $('#password').trigger('change');    }};/** *  * @returns {_L2.Registration@call;doAjax@call;then}**/Registration.validate = function(){    return this.doAjax().then(        $.proxy(this.handleResponse, this),        $.proxy(this.handleError, this)    );};/** *  * @param {type} response * @returns {undefined}**/Registration.handleResponse = function(response){    var field = $(this.options.context);    if(response.msg == 'success')    {        field.addClass('valid');    }    else    {        field.val('');        field.attr('placeholder', response.responseError);        field.addClass('invalid');    }    return;};/** *  * @param {type} error * @returns {undefined}**/Registration.handleError = function(error){    switch(error.code)    {        case 404:            return console.error('Not found');        break;        case 401:            return console.error('un-authorized access!');        break;        case 500:            return console.error('system error!');        break;    }};/** *  * @returns {unresolved}**/Registration.doAjax = function(){    return $.ajax(this.options).promise();}Registration.init();})(jQuery);
Implementing Ajax deferred/promise patterns
javascript;jquery;ajax;asynchronous