I am stuck with a function that has to process an array, and as part of this it has to loop over it and perform an ajax call using a value to determine if it's valid. If errors are found it returns a string of error messages after it has processed all the data. How do I ensure the ajax calls all complete before the functions returns, bearing in mind that they will only fire on some loops?
I've tried all sorts of deferred / promise related things but can't get it right :( I don't believe this is as straightforward as "how do I get return async data" due to the forEach, or even if the principle is the same I'm struggling with the implimentation.
Trimmed code below - note the // Do other stuffs - both within the forEach in case that makes a difference. A watcher calls handleFileSelect(), which then calls basicValidation();
function basicValidation( data ) {
    // Store errors to be returned.
    var failed = '';
    // Loop over each row and validate.
    data.forEach( function( row, index ) {
        // Do other stuff.
        if ( a ) {
            // Do stuff.
        } else if (b) {
            // Do ajax bit that only happen sometimes.
            $.ajax({
                url: 'https://api.postcodes.io/postcodes/' + row[5],
                success: function (data) {
                    if ( 200 !== data.status ) {
                        failed += 'Row ' + index + ':: invalid Address - lookup failed.\n';
                    }
                    // Do other checks.
                },
                error: function (request, status, error) {
                    console.log(  'Postcode lookup request failed:: ' + request.responseText + '\n' + status + '\n' + error );
                }
            });
        }
        // Do other stuff.
    }
    return failed;
}
function handleFileSelect( results ) {
    // Do the basic front-end validation.
    var validation = basicValidation( results.data );
    if ( validation.length ) {
        alert( 'Failed.\n\n' + validation + '\nPlease correct your data, refresh the page, and try again.' );
        return false;
    }
}
 
    