Скасувати попередній запит ajax за новим запитом


79

У мене є функція, яка запускає виклик ajax при зміні вводу.

Але є ймовірність того, що функція буде знову запущена до завершення попереднього виклику ajax.

Моє питання полягає в тому, як я можу перервати попередній виклик ajax перед початком нового? Без використання глобальної змінної. (Див. Відповідь на подібне запитання тут )

jsfiddle мого поточного коду:

Javascript:

var filterCandidates = function(form){
    //Previous request needs to be aborted.
    var request = $.ajax({
        type: 'POST',
        url: '/echo/json/',
        data: {
            json: JSON.stringify({
                count: 1
            })
        },
        success: function(data){
            if(typeof data !== 'undefined'){
                jQuery('.count').text(data.count)
                console.log(data.count);
            }
        }
    });
};

if(jQuery('#search').length > 0){
    var form = jQuery('#search');
    jQuery(form).find(':input').change(function() {
        filterCandidates(form);
    });
    filterCandidates(form);
}

HTML:

<form id="search" name="search">
    <input name="test" type="text" />
    <input name="testtwo" type="text" />
</form>
<span class="count"></span>

Заголовок вашого запитання неправильний. Це має бути Скасувати новий запит AJAX перед заповненням попереднього
— Абхішек Камаль

Відповіді:


112
 var currentRequest = null;    

currentRequest = jQuery.ajax({
    type: 'POST',
    data: 'value=' + text,
    url: 'AJAX_URL',
    beforeSend : function()    {           
        if(currentRequest != null) {
            currentRequest.abort();
        }
    },
    success: function(data) {
        // Success
    },
    error:function(e){
      // Error
    }
});

12
чи не повинні обидва обробники відповідей ( successі error) currentRequestповернутися до null?
— CodeManX

3
- запитав ОП how would I abort the previous ajax call. Але тут ви перериваєте currentRequestновий, новий варіант. Таким чином, попередній виконається, новий запит буде скасовано. Правда?
— phil294,

10
ах, ні. beforeSendце виконується передjqXHR тим об'єкт присвоюється currentRequest. Таким чином, попередній дзвінок там перервано. - завжди вдячні за добре коментовані відповіді
— phil294,

5
Це рішення не працює для мене у типі GET. Не перевіряв POST.
— Sanyam Jain

4
Хоча цей код може відповісти на питання, надання додаткового контексту щодо того, як і чому він вирішує проблему, покращило б довгострокову цінність відповіді.
— Олександр

10
var filterCandidates = function(form){
    //Previous request needs to be aborted.
    var request = $.ajax({
        type: 'POST',
        url: '/echo/json/',
        data: {
            json: JSON.stringify({
                count: 1
            })
        },
        success: function(data){
            if(typeof data !== 'undefined'){
                jQuery('.count').text(data.count)
                console.log(data.count);
            }
        }
    });
    return request;
};

var ajax = filterCandidates(form);

збережіть у змінну, а потім, перед надсиланням вдруге, перевірте її readyStateта зателефонуйте, abort()якщо потрібно


7
Це було простіше, ніж я собі уявляв. Я створив скрипту цієї роботи: jsfiddle.net/YzDBg/4 для всіх, хто зацікавлений. Дякую.
— CharliePrynn

7
Ви можете пояснити це детально, будь ласка?
— SSS

5

варіація прийнятої відповіді та прийнята з коментаря до питання - це чудово підійшло для моєї програми ....

за допомогою $ .post () jQuery ....

var request = null;

function myAjaxFunction(){
     $.ajaxSetup({cache: false}); // assures the cache is empty
     if (request != null) {
        request.abort();
        request = null;
     }
     request = $.post('myAjaxURL', myForm.serialize(), function (data) {
         // do stuff here with the returned data....
         console.log("returned data is ", data);
     });
}

Зателефонуйте myAjaxFunction () скільки завгодно разів, і він вбиває всіх, крім останнього (у моєму додатку є "селектор дати", і ціна змінюється залежно від вибраних днів - коли хтось швидко натискає на них без зазначеного коду жеребкування монети щодо того, чи отримають вони правильну ціну, чи ні. З нею це на 100% правильно!)


0

Спробуйте цей код

var lastCallFired=false;

var filterCandidates = function(form){

    if(!lastCallFired){
    var request = $.ajax({
        type: 'POST',
        url: '/echo/json/',
        data: {
            json: JSON.stringify({
                count: 1
            })
        },
        success: function(data){
            if(typeof data !== 'undefined'){
                jQuery('.count').text(data.count)
                console.log(data.count);
            }
        }
    });
        setInterval(checkStatus, 20);

    }

};

if(jQuery('#search').length > 0){
    var form = jQuery('#search');
    jQuery(form).find(':input').change(function() {
        filterCandidates(form);
    });
    filterCandidates(form);
}

var checkStatus = function(){
        if(request && request.readyState != 4){
            request.abort();
        }
    else{
        lastCallFired=true;
    }
};

0
if(typeof window.ajaxRequestSingle !== 'undefined'){
  window.ajaxRequestSingle.abort();
}

window.ajaxRequestSingle = $.ajax({
  url: url,
  method: 'get',
  dataType: 'json',
  data: { json: 1 },
  success: function (data) {
    //...
  },
  complete: function () {
    delete window.ajaxRequestSingle;
  }
});
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.