Sebenarnya ada perbedaan yang cukup penting, sejauh jQuery's Deferreds dimaksudkan untuk menjadi implementasi dari Janji (dan jQuery3.0 benar-benar mencoba untuk membawanya ke dalam spesifikasi).
Perbedaan utama antara dilakukan / kemudian adalah itu
.done()
SELALU mengembalikan nilai Janji / terbungkus yang sama dengan yang dimulainya, terlepas dari apa yang Anda lakukan atau apa yang Anda kembalikan.
.then()
selalu mengembalikan Janji BARU, dan Anda bertanggung jawab untuk mengendalikan apa yang dijanjikan berdasarkan pada fungsi yang Anda berikan untuk mengembalikannya.
Diterjemahkan dari jQuery ke ES2015 Promises asli, .done()
adalah semacam menerapkan struktur "ketuk" di sekitar fungsi dalam rantai Janji, dalam hal itu akan, jika rantai tersebut dalam keadaan "tekad", berikan nilai ke fungsi. ... tetapi hasil dari fungsi itu TIDAK akan mempengaruhi rantai itu sendiri.
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));
Keduanya akan log 5, bukan 6.
Perhatikan bahwa saya menggunakan done dan doneWrap untuk melakukan logging, bukan .then. Itu karena fungsi console.log tidak benar-benar mengembalikan apa pun. Dan apa yang terjadi jika Anda lulus. Lalu fungsi yang tidak mengembalikan apa pun?
Promise.resolve(5)
.then(doneWrap( x => x + 1))
.then(console.log.bind(console))
.then(console.log.bind(console));
Itu akan masuk:
5
tidak terdefinisi
Apa yang terjadi? Ketika saya menggunakan .then dan meneruskannya fungsi yang tidak mengembalikan apa pun, hasilnya implisit adalah "tidak terdefinisi" ... yang tentu saja mengembalikan Janji [tidak terdefinisi] ke metode selanjutnya, yang dicatat tidak terdefinisi. Jadi nilai awal yang kami mulai pada dasarnya hilang.
.then()
pada dasarnya adalah bentuk komposisi fungsi: hasil dari setiap langkah digunakan sebagai argumen untuk fungsi di langkah berikutnya. Karena itulah .done dianggap sebagai "tap" -> itu sebenarnya bukan bagian dari komposisi, hanya sesuatu yang menyelinap melihat nilai pada langkah tertentu dan menjalankan fungsi pada nilai itu, tetapi tidak benar-benar mengubah komposisi dengan cara apa pun.
Ini adalah perbedaan yang cukup mendasar, dan mungkin ada alasan bagus mengapa Janji asli tidak memiliki metode .done dilaksanakan sendiri. Kita tidak harus membahas mengapa tidak ada metode .fail, karena itu bahkan lebih rumit (yaitu, .fail / .catch BUKAN mirror dari fungsi .done / .then -> dalam .catch yang mengembalikan nilai telanjang tidak menghasilkan "tetap" ditolak seperti yang diteruskan. lalu, mereka menyelesaikan!)