$.ajax returns a jqXHR and it behaves like a promise

$.ajax takes success and error options, so most code passes callbacks in and stops there. It also returns a jqXHR, which has implemented the Deferred interface since 1.5 — meaning the function that makes the request does not have to know what happens with the answer.

// the option callback: only attachable at the call site
$.ajax({ url: '/basket', success: render });

// the returned jqXHR: attachable later, by whoever needs it
function loadBasket() {
    return $.ajax({ url: '/basket', dataType: 'json' });
}

loadBasket().done(render).fail(showError).always(hideSpinner);

$.when(loadBasket(), $.get('/shipping'))
 .done(function (basket, shipping) {
     // each argument is [ data, statusText, jqXHR ]
 });

Returning the jqXHR is the whole gain: loadBasket() stops deciding what happens next, and two callers can want different things from the same request. The trap is $.when. Given a single deferred it passes the resolution arguments through spread out, so the handler receives data, statusText, jqXHR; given two or more it passes one array per deferred. Adding a second request therefore changes the shape of the first argument without any error, and the code that read basket.lines now reads it off an array. Take the data as basket[0] from the start. .pipe() still works but .then() has returned a filtered promise since 1.8, so .pipe() is the one to stop writing.