En realidad, hay una diferencia bastante crítica, en la medida en que los aplazamientos de jQuery están destinados a ser implementaciones de Promesas (y jQuery3.0 en realidad trata de ponerlas en especificación).
La diferencia clave entre hecho / entonces es que
.done()
SIEMPRE devuelve los mismos valores Promise / wrap con los que comenzó, independientemente de lo que haga o lo que devuelva.
.then()
siempre devuelve una NUEVA promesa, y usted está a cargo de controlar qué promesa se basa en la función que le devolvió.
Traducido de jQuery a Promesas ES2015 nativas, .done()
es como implementar una estructura "tap" alrededor de una función en una cadena Promise, en el sentido de que, si la cadena está en el estado "resolver", pasará un valor a una función. . pero el resultado de esa función NO afectará la cadena en sí.
const doneWrap = fn => x => { fn(x); return x };
Promise.resolve(5)
.then(doneWrap( x => x + 1))
.then(doneWrap(console.log.bind(console)));
$.Deferred().resolve(5)
.done(x => x + 1)
.done(console.log.bind(console));
Ambos registrarán 5, no 6.
Tenga en cuenta que usé done y doneWrap para hacer el registro, no .then. Eso es porque las funciones de console.log en realidad no devuelven nada. ¿Y qué pasa si pasa .then una función que no devuelve nada?
Promise.resolve(5)
.then(doneWrap( x => x + 1))
.then(console.log.bind(console))
.then(console.log.bind(console));
Eso registrará:
5 5
indefinido
¿Que pasó? Cuando utilicé .then y le pasé una función que no devolvió nada, su resultado implícito fue "indefinido" ... lo que, por supuesto, devolvió una Promesa [indefinida] al siguiente método, que se registró indefinido. Entonces, el valor original con el que comenzamos se perdió básicamente.
.then()
es, en el fondo, una forma de composición de funciones: el resultado de cada paso se usa como argumento para la función en el siguiente paso. Es por eso que .done se considera mejor como un "toque" -> en realidad no es parte de la composición, solo algo que muestra un poco el valor en un determinado paso y ejecuta una función en ese valor, pero en realidad no altera La composición de cualquier manera.
Esta es una diferencia bastante fundamental, y probablemente haya una buena razón por la cual las Promesas nativas no tienen implementado un método .done. No tenemos que entender por qué no hay un método .fail, porque eso es aún más complicado (a saber, .fail / .catch NO son espejos de las funciones .done / .then -> en .catch que devuelven valores simples no "permanecer" rechazado como los que se pasan a. ¡Entonces, se resuelven!)