Дождитесь AJAX, прежде чем продолжить через отдельную функцию


Хорошо... в 2 часа ночи здесь я провожу черту. Помогите... пока мой ноутбук не вылетел в окно. :)

Я пробовал использовать setTimer, обратные вызовы и все остальное, что я могу придумать (наряду с несколькими другими подсказками Stackoverflow, конечно). Я вычеркнул все, поэтому оставляю только базовый код.

То, что я хочу сделать, - это вызвать parseRow() , и прежде чем он сохранит запись в конце, мне нужно захватить соответствующую категорию (через AJAX); однако, он проходит мимо это так категория всегда "неопределенная".

function parseRow(row){
    var rowArray     = row.trim().split(",");
    var date         = rowArray[0];
    var checknum     = rowArray[1];
    var payee        = rowArray[2];
    var memo         = rowArray[3];
    var amount       = rowArray[4];

    //ERROR: blows right past this one and sets the category variable BEFORE ajax returns
    var category = autoSelectCategory(payee);

    saveRecord(date, checkNum, payee, memo, category, payment, deposit);
}

function autoSelectCategory(payee) {
    var data;
    $.ajax({
        async: false,
        url: "autoselectcategory",
        dataType: "json",
        data: {
            string: payee
        },
        success: function (returnedData) {
            data = returnedData;
        }
    });
    return data;
}
2   8  

2 ответа:

AJAX означаетасинхронный . Это означает, что в исходном коде saveRecord будет выполняться до того, как клиент получит ответ от сервера (и, в зависимости от реализации $.ajax, это может быть до того, как клиент отправит запрос на сервер).

Кроме того, вы, кажется, неправильно понимаете, как функции работают в JS. var category = autoSelectCategory(payee); установит для категории возвращаемое значение autoSelectCategory; но функция autoSelectCategory в вашем коде возвращает ничего.

С другой стороны, возвращаемое значение data анонимной функции может использоваться только функцией $.ajax$.ajax, скорее всего, игнорирует возвращаемое значение параметра success).

Вот код, который должен работать:

function parseRow(row){
    var rowArray     = row.trim().split(",");
    var date         = rowArray[0];
    var checknum     = rowArray[1];
    var payee        = rowArray[2];
    var memo         = rowArray[3];
    var amount       = rowArray[4];

    autoSelectCategory(payee, function (category) {    
        saveRecord(date, checkNum, payee, memo, category, payment, deposit);
    });
}

function autoSelectCategory(payee, callback) {
    $.ajax({
        async: false,
        url: "autoselectcategory",
        dataType: "json",
        data: {
            string: payee
        },
        success: callback
    });
}

Не используйте опцию async: false. Это чистое зло (блокируетвсе скрипты в браузере и даже на других вкладках!) и он устарел с jQuery 1.8. Вы должны использовать обратные вызовы, как это всегда было задумано.

function parseRow(row) {
    /* the other code */
    autoSelectCategory(payee, function() {
        saveRecord(date, checkNum, payee, memo, category, payment, deposit);
    });
}

function autoSelectCategory(payee, callback) { // <---- note the additional arg
    $.ajax({
        url: "autoselectcategory",
        dataType: "json",
        data: {
            string: payee
        },
        success: function(res) {
            /* the other code */
            callback();
        }
    });
}