Скрываем логику проверки ответа асинхронного запроса

С помощью Deferred Object легко скрыть логику проверки ответа асинхронного запроса.

Считаем, что запрос отработан успешно, если с сервера вернулся JSON и поле status в объект установлено в значение ok. Если там оказалось другое значение, то запрос завершился с ошибкой.

Из метода возвращаем не Deferred XHR, а новый экземпляр обычного отложенного объекта, который в дальнейшем будем «реджектить» или «резолвить».

function subscribe(objectId) {
    var dfd = $.Deferred(),
        p = dfd.promise();

    $.ajax({
        url: "/subscribe",
        type: "post",
        data: {
            objectId: objectId
        }
    }).done(function (data) {
        if (data) {
            if (data.status == "ok") {
                dfd.resolveWith(p);
            } else {
                dfd.rejectWith(p, [data.status]);
            }
        } else {
            dfd.rejectWith(p, ["wrong response"]);
        }
    }).fail(function () {
        dfd.rejectWith(p, ["communication error"]);
    });

    return p;
}

Так как логика обработки ответа отделена от логики приложения, то эта часть кода — хороший кандидат на выделение её в общий для всего приложения обработчик.