Насправді є досить критична відмінність, наскільки відкладені jQuery мають на увазі реалізацію Promises (а jQuery3.0 намагається перевести їх у специфікацію).
Ключова різниця між зробленим / тоді в тому
.done()
ЗАВЖДИ повертає ті самі значення Обіцяння / завершені, з яких він розпочався, незалежно від того, що ви робите чи що ви повертаєте.
.then()
завжди повертає НОВУ Обіцянку, і ви відповідаєте за те, щоб контролювати те, на чому ця Обіця базується на тому, яку функцію ви її передали.
Перекладене з jQuery на рідну ES2015 Promises, .done()
це як би реалізація структури "tap" навколо функції у ланцюзі Promise, завдяки чому вона, якщо ланцюг перебуває у стані "вирішення", передасть значення функції .. але результат цієї функції НЕ вплине на саму ланцюг.
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));
Вони будуть входити в журнал 5, а не 6.
Зауважте, що я використовував done and doneWrap для ведення журналів, а не потім. Це тому, що функції console.log насправді нічого не повертають. А що станеться, якщо ви перейдете. Тоді функцію, яка нічого не повертає?
Promise.resolve(5)
.then(doneWrap( x => x + 1))
.then(console.log.bind(console))
.then(console.log.bind(console));
Це буде журнал:
5
невизначений
Що трапилось? Коли я застосував. Тож початкове значення, з якого ми почали, в основному було втрачено.
.then()
по суті є формою композиції функції: результат кожного кроку використовується як аргумент функції на наступному кроці. Ось чому .done найкраще розглядати як "дотик" -> це насправді не частина композиції, а лише те, що підкрадається погляд на значення на певному кроці і виконує функцію за цим значенням, але насправді не змінює композиція будь-яким способом.
Це досить принципова відмінність, і, ймовірно, є вагомою причиною того, що в "Обіцяннях" немає методу .done. Нам не потрібно вникати, чому немає методу .fail, тому що це ще складніше (а саме .fail / .catch НЕ є дзеркалами функцій .done / .then -> в .catch, які повертають голі значення не "Залишайтеся" відхиленими, як ті, що передаються. Потім вони вирішуються!)