vyshkant
@vyshkant
developer

Как одновременно вернуть переменную и promise при вызове ajax'а в функции (JQuery)?

Здравствуйте!
Вас приветствует велосипедный завод имени меня :)
Столкнулся со следующей проблемой.
Есть форма. В JQuery есть событие submit, которое ловится:
$(".TTWForm").validator({effect:'labelMate'}).submit(function(e){
    ...
    return false; // предотвращает отправку формы
});

Собственно, в коде хендлера submit'а происходит отправка формы по ajax'у. НО.
Появилась необходимость проверить некоторые денные из формы перед отправкой, и если данные не подходят - не отправлять форму. Конкретно: там есть интервал дат, который сверяется с интервалом дать из БД. Происходит всё это дело при помощи функции dates_validator():
dates_validator = function(result) {
        if (...) { // если в форме заполнены необходимые для проверки дат поля
            
        // сделать, чтобы функция дождалась ответа аякса, а затем вернула 0/1
            var dfd;
            dfd = new $.Deferred();
            
            $.ajax({
                ...
                success: function(answer){
                    data = $.parseJSON(answer);
                    if (data.status == 'error'){
                        ...
                        result.check = 0;
                    } else if (data.status == 'success') {
                        ...
                        result.check = 1;
                    }
                    dfd.resolve();
                }
            });
            return dfd.promise();
        } else {
            return 0;
        }
    };

Далее, соответственно, эта функция вызывается из тела хендлера submit'а:
$(".TTWForm").validator({effect:'labelMate'}).submit(function(e){
        var result = {};
        var promise = dates_validator(result);
        
        $.when.apply($, promise).then(function(){
            alert(result.check);
            console.log(result);
            ... // тут должна быть отправка формы по аяксу
               //или неотправка, если result.check == 0
         }
    }

Собственно, моя идея была такой: функция возвращает promise через return, а также устанавливает значение result.check. Поскольку мы обращаемся к result.check уже после получения promise, то мне казалось, что он уже гарантированно будет заполнен нулем или единицей (в функции dates_validator).
Но, нет :)
Alert показывает undefined, в то время как console.log показывает значение check == 1, с пометкой (Object state below is captured upon first expansion).

Собственно, я уже задавал похожий вопрос (Как заставить javascript дождаться ответа ajax'а?), но там были немного другие условия задачи, да и до меня, видимо, не дошла суть.

Собственно, вопрос: как сделать чтобы всё работало?)) Ну т.е. задача в двух словах: вытянуть из функции dates_validator() не только promise, но и еще один бит информации - ноль или единицу.

Спасибо.

UPD
Проблема решена следующим образом:
1) Функция-валидатор:
dates_validator = function(result) {
        var dfd;
        dfd = new $.Deferred();
        if (...) { // если в форме заполнены необходимые для проверки дат поля
        var result;
            $.ajax({
                ...
                success: function(answer){
                    if (){
                        ...
                        result = 0;
                    } else {
                        ...
                        result = 1;
                    }
                    dfd.resolve(result);
                }
            });
            return dfd.promise();
        } else {
            dfd.resolve(0);
            return dfd.promise();
        }
    };

2) Хендлер submit'а:
$(".TTWForm").validator({effect:'labelMate'}).submit(function(e){
        var form = $(this), checkRadioValidation = validateCheckRadio();
        
        date_promise = dates_validator();

        date_promise.done(function(result){
            alert("result: "+result);
            console.log("result: "+result);
            ... // тут отправка/неотправка формы по аяксу в зависимости от result
        });
        return false;
    });
  • Вопрос задан
  • 944 просмотра
Решения вопроса 1
standy
@standy
Подозрительная конструкция
$.when.apply($, promise)
Вторым аргументом должен идти массив.
Мне кажется можно обойтись без нее, просто promise.then
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
BRAGA96
@BRAGA96
asynchronous().then(function (data) {
    console.log(data); //> "test"
});

function promise(callback) {
    var deferred = $.Deferred();
    callback & callback(deferred.resolve, deferred.reject);
    return deferred;
}

function asynchronous() {
    return promise(function (resolve ,reject) {
        resolve('test');
    });
}
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы