Jest tak naprawdę dość istotna różnica, o ile Odroczone jQuery mają być implementacjami Obietnic (a jQuery3.0 faktycznie próbuje wprowadzić je w specyfikację).
Kluczowa różnica między wykonaniem / następnie jest taka
.done()
ZAWSZE zwraca te same obietnice / zapakowane wartości, od których zaczął, niezależnie od tego, co robisz lub co zwracasz.
.then()
zawsze zwraca NOWĄ obietnicę, a ty jesteś odpowiedzialny za kontrolowanie, co ta obietnica jest oparta na funkcji, którą przekazałeś.
Przetłumaczone z jQuery na natywne obietnice ES2015, .done()
jest coś w rodzaju implementacji struktury „dotknij” wokół funkcji w łańcuchu obietnicy, w tym sensie, że jeśli łańcuch jest w stanie „rozstrzygnięcia”, przekaże wartość do funkcji .. , ale wynik tej funkcji NIE wpłynie na sam łańcuch.
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));
Oba będą rejestrować 5, a nie 6.
Zauważ, że użyłem done i doneWrap do rejestrowania, a nie. Następnie. To dlatego, że funkcje console.log nie zwracają niczego. A co się stanie, jeśli zdasz. Następnie funkcję, która nic nie zwraca?
Promise.resolve(5)
.then(doneWrap( x => x + 1))
.then(console.log.bind(console))
.then(console.log.bind(console));
To będzie rejestrować:
5
nieokreślony
Co się stało? Kiedy użyłem .the i przekazałem mu funkcję, która niczego nie zwróciła, jej domyślnym rezultatem było „niezdefiniowane” ... co oczywiście zwróciło Obietnicę [niezdefiniowana] do następnej metody, która zalogowała się niezdefiniowana. Tak więc pierwotna wartość, od której zaczęliśmy, została zasadniczo utracona.
.then()
jest w istocie formą kompozycji funkcji: wynik każdego kroku jest wykorzystywany jako argument funkcji w następnym kroku. Właśnie dlatego .done najlepiej jest traktować jako „stuknięcie” -> to nie jest tak naprawdę część kompozycji, tylko coś, co rzuca okiem na wartość na pewnym etapie i uruchamia funkcję przy tej wartości, ale tak naprawdę nie zmienia kompozycja w jakikolwiek sposób.
Jest to dość podstawowa różnica i prawdopodobnie istnieje dobry powód, dla którego natywne obietnice nie mają zaimplementowanej metody .done. Nie musimy się zastanawiać, dlaczego nie ma metody .fail, ponieważ jest to nawet bardziej skomplikowane (mianowicie .fail / .catch NIE są dublowaniem funkcji .done / .the -> funkcje w .catch, które zwracają same wartości, nie „zostań” odrzucony tak, jak te przekazane do. następnie rozwiązują!)