Подтвердить что ты не робот

JQuery Отложенное: отклонение обещания из встроенного фильтра

Fyi, я только начинаю изучать jQuery promises, поэтому я немного запутался здесь.

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

return doAJAXRequest().then(function (data) {
    if (data.responseText == "YES") {
        return doOtherAJAXRequest();
    } else {
        this.reject(data);
    }
});

Это не сработало, как я ожидал:

Uncaught TypeError: Object #<Object> has no method 'reject'

Как я могу сделать это обещание неудачным на основе его ответа? Это возможно? Или я просто смущен тем, что нужно сделать здесь?

4b9b3361

Ответ 1

В jQuery (в отличие от некоторых других libs), преобразование обещания из "разрешенного" состояния в "отклоненное" состояние немного подробное, требующее явного создания и отклонения нового Отложенного.

function foo() {
    return doAJAXRequest().then(function (data, textStatus, jqXHR) {
        if (data.responseText == "YES") {
            return doOtherAJAXRequest(data);
        } else {
            return $.Deferred().reject(jqXHR, data, 'Not YES').promise();
        }
    });
)

Здесь обещание возвращается, если data.responseText !== "YES" имитирует (частично) неудачный запрос ajax, но все же позволяет передать data. Это (вероятно) важно для обработчика downstream .fail(), который должен обрабатывать как настоящие аякс-неудачи, так и претерпелизированные условия успеха, не зная, какой из них произошел до тех пор, пока он не прочитает errorThrown.

foo().fail(function(jqXHR, textStatus, errorThrown) {
    if(errorThrown == 'Not YES') {
        //transmogrified success
        var data = textStatus;
        ...
    }
    else {
        //genuine ajax failure
        ...
    }
}); 

Обычно проще передать data таким образом, а не повторно получать его из объекта jqXHR. Это особенно верно для JSON-кодированных данных, которые в противном случае необходимо было бы декодировать второй раз в обработчике сбоев.