Можете ли вы остановить отложенный обратный вызов в jquery 1.5?

Мне интересно, скажите, у вас есть что-то вроде этого

// Assign handlers immediately after making the request,
// and remember the jqxhr object for this request
var jqxhr = $.ajax({ url: "example.php" })
    .success(function(response) { alert("success"); })


// perform other work here ...

// Set another success function for the request above
jqxhr.success(function(response){ alert("second success"); });

Так что я думаю об этом. У меня есть общая функция, которую я хочу использовать для всех своих ответов, которые будут переданы в мой успех.

Эта функция в основном проверяет, обнаружила ли проверка сервера какие-либо ошибки. Если это так, они форматируют его и отображают сообщение.

Теперь мне интересно, могу ли я как-то использовать вторую функцию успеха, чтобы затем делать определенные вещи. Например, один запрос ajax должен добавить строку в таблицу. Так что это должно быть возможно. Я просто делаю то, что у меня есть выше, и во втором успехе я просто добавляю строку.

Однако возможно ли, что если первый успех пройдет и я увижу, что на сервере есть ошибки проверки, я могу предотвратить второй успех?

Вроде, как бы, что-то вроде

If(first success finds errors)
{
   // print out errors
   // don't continue onto next success
}
else
{
   // go to next success 
}

Изменить

Я обнаружил, что есть нечто, называемое deferred.reject , и это останавливает его, но мне интересно, как могу ли я указать, чтобы остановить только успех. Поскольку я думаю, что если есть другие отложенные, такие как завершенные, они тоже будут отклонены?


person chobo2    schedule 02.03.2011    source источник


Ответы (3)


Если у вас есть только одна функция проверки проверки, вы можете создать свои собственные отложенные и прикрепить к ней обработчики, а не напрямую к запросу ajax.

Этот пример дает один уровень проверки, если вы хотите связать их вместе, вам может понадобиться другой шаблон.

var validated = function(jqxhr, validationFunction){
    var myDeferred = new $.Deferred();
    var doValidation = function(){
        var result = validationFunction.apply(this, arguments);
        if (result){
            myDeferred.resolve(arguments);
        }
        else
        {
            myDeferred.reject(arguments);
        }
    };

    jqxhr.success(doValidation);
    return myDeferred;
};

var jqxhr = $.ajax({ url: "/echo/json/"});
var vtest = validated(jqxhr, function(response){
    //Do your validation check here,
    //return true if it passed, false if it failed.
    return false; 
});

//attach your handlers to vtest
vtest.done(function(response){alert("yay");});
vtest.fail(function(response){alert("drats");});
person david    schedule 03.03.2011

Вызовите свою вторую функцию успеха, когда ваша первая функция успеха оценивает ответ от вызова AJAX и определяет, что он соответствует вашим требованиям.

пример:

$.post('example.php', {name_1: value_1, name_2: value_2}, function(response){
  //this code gets executed when the AJAX request was successful

  //do some more stuff

  //check the response
  if(response == 'success'){
    second_success_function(response);
  }
});

В этом примере предполагается, что вы получили строку «успех», когда все прошло по плану.

Второй аргумент в вызове $.post — это карта значений, которые вы передаете сценарию. Это необязательно.

Вы также можете назначить обработчик, который будет выполняться после завершения всех запросов AJAX.

http://api.jquery.com/ajaxStop/

person Kyle    schedule 02.03.2011

Насколько я знаю, нет, вы не можете использовать отложенный объект (как в jQuery v1.5 .ajax() объекты расширяют отложенные объекты) вот так.

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

Возможно, лучше выполнить необходимую логику в вашей функции успеха и вызвать функцию-оболочку, которая позаботится о любых повторяющихся действиях и вызовет ее из успеха, если ваши логические тесты пройдут.


Обновление согласно комментариям:

var cs = true;
var jqxhr = $.ajax({ 
    beforeSend: function(){
        cs=true;
    },
    url: "/echo/json/" 
})

.success(function(response) { 
    if(cs)
    alert("success"); 
})

.success(function(response) { 
    if(cs)
        cs = false;
        alert("success 2"); 
})

.success(function(response) { 
    if(cs)
        alert("success 3"); 
});

Использование логики для отключения обратных вызовов.

person Scoobler    schedule 02.03.2011
comment
Когда я попытался отклонить это, это остановило мой второй успех. Если я вас правильно понимаю, причина, по которой это, вероятно, сработало, заключается в том, что при первом успехе происходит отказ, поэтому технически он не завершен? - person chobo2; 03.03.2011
comment
@Scoobler- тогда я не понимаю, какой смысл иметь несколько успешных обратных вызовов. Я подумал, может быть, это так, чтобы вы могли сделать что-то вроде того, что я пытаюсь сделать, но это не похоже на тот случай. - person chobo2; 03.03.2011
comment
Не совсем, как я понимаю, когда вы создаете объект, он складывает все обратные вызовы (успешно), а затем, как только объект завершен (был вызван либо отказ, либо разрешение) затем он обработает стек. В конце концов, это обратные вызовы, что-то, что должно быть выполнено после того, как объект закончит свою работу - они не текут, то есть строка за строкой. Еще раз взгляните на это обновление. Другое дело, что как только объект получает вызов для разрешения, я не думаю, что он должен быть изменен или отклонен. - person Scoobler; 03.03.2011
comment
На самом деле нет смысла складывать успешные обратные вызовы. Это просто то, что вы можете сделать. На самом деле, чего добился jQuery, сделав .ajax() отложенным объектом, так это позволить вам более открыто взаимодействовать с объектом. Таким образом, вы можете использовать .then() вместо .success() и .done()' instead of .complete()`. Однако вы МОЖЕТЕ использовать некоторую логику во всех обратных вызовах. - person Scoobler; 03.03.2011
comment
Смотрите обновление вопроса. Это не самое красивое, в основном перед вызовом ajax установите флаг cs (продолжить успех) в true. Пока это правда, продолжайте. Проблема в том, что если у вас было несколько вызовов ajax одновременно, глобальный var cs мог быть затронут неправильным обратным вызовом. - person Scoobler; 03.03.2011