plugins/validation/index.js
function runValidation(validators, field, context, callback) {
    var fieldErrors = [];
    var pending = 0;

    function saveResult(result) {
        if (result !== true) {
            fieldErrors.push(result);
        }
    }

    function doCallback() {
        callback(fieldErrors);
    }

    function asyncValidationDone(result) {
        saveResult(result);
        pending--;
        pending === 0 && doCallback();
    }

    validators.forEach(function (validator) {
        if (validator.length === 2) {
            pending++;
            validator.call(context, field, asyncValidationDone);
        } else {
            saveResult(validator.call(context, field));
        }
    });

    if (pending === 0) {
        // synchronous callback
        doCallback();
    }

    return fieldErrors;
}
function runValidation(validators, field, context, callback) {
    var fieldErrors = [];
    var pending = 0;

    function saveResult(result) {
        if (result !== true) {
            fieldErrors.push(result);
        }
    }

    function doCallback() {
        callback(fieldErrors);
    }

    function asyncValidationDone(result) {
        saveResult(result);
        pending--;
        pending === 0 && doCallback();
    }

    validators.forEach(function (validator) {
        if (validator.length === 2) {
            pending++;
            validator.call(context, field, asyncValidationDone);
        } else {
            saveResult(validator.call(context, field));
        }
    });

    if (pending === 0) {
        // synchronous callback
        doCallback();
    }

    return fieldErrors;
}
function runValidation ( validators , field , context , callback ) { var fieldErrors = [ ] ; var pending = 0 ; function saveResult ( result ) { if ( result !== true ) { fieldErrors . push ( result ) ; } } function doCallback ( ) { callback ( fieldErrors ) ; } function asyncValidationDone ( result ) { saveResult ( result ) ; pending -- ; pending === 0 && doCallback ( ) ; } validators . forEach ( function ( validator ) { if ( validator . length === 2 ) { pending ++ ; validator . call ( context , field , asyncValidationDone ) ; } else { saveResult ( validator . call ( context , field ) ) ; } } ) ; if ( pending === 0 ) { // synchronous callback doCallback ( ) ; } return fieldErrors ; }
Runs the given validators on a single field.

Caution: callback will be called in synchronously in some situations. This behavior should usually be avoided in
public APIs, but since runValidation() is internal, we know how to deal with it. It allows us to speed up
validation and to return all synchronous validation results as soon as possible.

The final callback, however, is guaranteed to be asynchronous.

@param {Array} validators
@param {*} field
@param {Object} context
@param {Function} callback
@returns {Array}
Runs the given validators on a single field .