2012-01-12 4 views
264

Я работаю с jQuery и AJAX в течение нескольких недель, и я видел два разных способа «продолжить» сценарий после того, как был сделан звонок: success: и .done.jQuery.ajax обработка ответов: «success:» vs «.done»?

Из конспекта из jQuery documentation мы получаем:

.done(): Описание: Добавить обработчики будут вызываться, когда Отложенный объект решен.

success: (.ajax() option): Функция, вызываемая, если запрос завершается успешно.

Итак, оба выполняют что-то после завершения/разрешения вызова AJAX. Могу ли я использовать одно или другое случайно? В чем разница и когда один используется вместо другого?

ответ

399

success было традиционным именем обратного вызова успеха в jQuery, определяемом как опция в вызове ajax. Однако, поскольку реализация $.Deferreds и более сложные обратные вызовы, done является предпочтительным способом реализации успешных обратных вызовов, поскольку его можно вызывать на любом deferred.

Например, успех:

$.ajax({ 
    url: '/', 
    success: function(data) {} 
}); 

Например, сделано:

$.ajax({url: '/'}).done(function(data) {}); 

Хорошая вещь о done является то, что возвращаемое значение $.ajax теперь отложенное обещание, которое может быть связано с где-нибудь еще в вашем приложении. Итак, допустим, вы хотите сделать этот вызов ajax из нескольких разных мест. Вместо того, чтобы передавать свою функцию успеха в качестве функции функции, которая делает этот аякс-вызов, вы можете просто вернуть функцию $.ajax и связать свои обратные вызовы с done, fail, then или что угодно. Обратите внимание, что always - это обратный вызов, который будет запускаться, будет ли запрос успешным или неудачным. done будет срабатывать только при успешном завершении.

Например:

function xhr_get(url) { 

    return $.ajax({ 
    url: url, 
    type: 'get', 
    dataType: 'json', 
    beforeSend: showLoadingImgFn 
    }) 
    .always(function() { 
    // remove loading image maybe 
    }) 
    .fail(function() { 
    // handle request failures 
    }); 

} 

xhr_get('/index').done(function(data) { 
    // do stuff with index data 
}); 

xhr_get('/id').done(function(data) { 
    // do stuff with id data 
}); 

Важное преимущество этого с точки зрения ремонтопригодности является то, что вы завернуты свой механизм AJAX в качестве функции конкретного приложения. Если вы решите, что вам нужен ваш звонок $.ajax для работы по-разному в будущем, или вы используете другой метод ajax или вы удаляетесь от jQuery, вам нужно только изменить определение xhr_get (обязательно верните обещание или, по крайней мере, done метод, в случае примера выше). Все остальные ссылки в приложении могут оставаться неизменными.

Есть много больше (гораздо круче) вещей, которые вы можете сделать с $.Deferred, один из которых является использование pipe, чтобы вызвать сбой на ошибку, сообщенный сервером, даже если сам $.ajax запрос выполнен успешно.Например:

function xhr_get(url) { 

    return $.ajax({ 
    url: url, 
    type: 'get', 
    dataType: 'json' 
    }) 
    .pipe(function(data) { 
    return data.responseCode != 200 ? 
     $.Deferred().reject(data) : 
     data; 
    }) 
    .fail(function(data) { 
    if (data.responseCode) 
     console.log(data.responseCode); 
    }); 
} 

xhr_get('/index').done(function(data) { 
    // will not run if json returned from ajax has responseCode other than 200 
}); 

Подробнее о $.Deferred здесь: http://api.jquery.com/category/deferred-object/

ПРИМЕЧАНИЕ: По состоянию на JQuery 1.8, pipe устаревшим в пользу использования then точно таким же образом.

+2

Интересно, как определяются взаимодействия 'success:' /'.done() ', если вообще. Например. это 'success:' только что реализованный как первый '.done()' в эти дни? –

+5

Вы имеете в виду, если у вас есть оба успеха: 'и' .done' при вызове ajax? Хороший вопрос. Поскольку все остальные обратные вызовы вызываются в том порядке, в котором они связаны, я предполагаю, что да, 'success' только что называется первым. – glortho

+1

Да, это действительно так: http://jsfiddle.net/9L7dD/ – Adam

2

Если вам нужно async: false в вашем ajax, вы должны использовать success вместо .done. Иначе вам лучше использовать .done. Это от jQuery official site:

По JQuery 1.8, использования асинхронные: ложные с jqXHR ($ .Deferred) является устаревшим; Вы должны использовать успеха/ошибки/полные варианты обратных вызова вместо соответствующих методов объекта jqXHR, такие как jqXHR.done().

Смежные вопросы