jQuery Deferred and native Promises are not the same object

jQuery has had $.Deferred since long before the platform had promises, and it is close enough to look interchangeable. It is not: prior to 3.0 a jQuery Deferred does not follow Promises/A+, and the difference shows up exactly where it hurts.

$.get('/api/orders')
    .then(function (data) {
        throw new Error('boom');   // swallowed by jQuery 1.x/2.x
    })
    .fail(function () {
        // never called for a thrown error
    });

A throw inside a native promise chain rejects the chain. In jQuery 1.x and 2.x it is not caught and does not reject — the failure disappears. Callbacks also fire synchronously if the deferred is already resolved, so ordering differs from native. Wrapping with Promise.resolve($.get(...)) at the boundary is the cheapest way to get consistent semantics for the rest of the chain.