jQuery Deferred
memiliki dua fungsi yang dapat digunakan untuk mengimplementasikan rangkaian fungsi asinkron:
then()
deferred.then( doneCallbacks, failCallbacks ) Returns: Deferred
doneCallbacks Sebuah fungsi, atau larik fungsi, dipanggil saat Deferred diselesaikan.
failCallbacks Sebuah fungsi, atau larik fungsi, dipanggil saat Deferred ditolak.
pipe()
deferred.pipe( [doneFilter] [, failFilter] ) Returns: Promise
doneFilter Fungsi opsional yang dipanggil saat Deferred diselesaikan.
failFilter Fungsi opsional yang disebut ketika tangguhan ditolak.
Saya tahu then()
telah ada sedikit lebih lama dari pipe()
itu yang terakhir harus menambahkan beberapa manfaat tambahan, tetapi apa perbedaan yang sebenarnya tidak saya ketahui. Keduanya mengambil hampir semua parameter callback yang sama meskipun mereka berbeda dalam nama dan perbedaan antara mengembalikan Deferred
dan mengembalikan Promise
nampaknya sedikit.
Saya telah membaca dokumen resmi berulang kali tetapi selalu merasa terlalu "padat" untuk benar-benar membungkus kepala saya dan pencarian telah menemukan banyak diskusi tentang satu fitur atau yang lain tetapi saya belum menemukan apa pun yang benar-benar menjelaskan perbedaannya pro dan kontra masing-masing.
Jadi kapan lebih baik digunakan then
dan kapan lebih baik digunakan pipe
?
Tambahan
Jawaban Felix yang luar biasa benar-benar membantu memperjelas bagaimana kedua fungsi ini berbeda. Tapi saya bertanya-tanya apakah ada kalanya fungsionalitas then()
lebih disukai daripada pipe()
.
Jelas bahwa pipe()
itu lebih kuat daripada then()
dan tampaknya yang pertama dapat melakukan apa pun yang dapat dilakukan oleh yang terakhir. Salah satu alasan untuk menggunakan then()
mungkin karena namanya mencerminkan perannya sebagai penghentian rantai fungsi yang memproses data yang sama.
Tetapi apakah ada kasus penggunaan yang mengharuskan then()
pengembalian yang asli Deferred
yang tidak dapat dilakukan pipe()
karena mengembalikan yang baru Promise
?
sumber
Jawaban:
Karena jQuery 1.8
.then
berperilaku sama seperti.pipe
:dan
Contoh di bawah ini mungkin masih berguna bagi sebagian orang.
Mereka melayani tujuan yang berbeda:
.then()
digunakan kapan pun Anda ingin bekerja dengan hasil dari proses tersebut, misalnya seperti yang dikatakan dalam dokumentasi, saat objek yang ditangguhkan diselesaikan atau ditolak. Ini sama dengan menggunakan.done()
atau.fail()
.Anda akan menggunakan
.pipe()
untuk (pra) memfilter hasilnya. Nilai kembali dari panggilan balik ke.pipe()
akan diteruskan sebagai argumen kedone
danfail
panggilan balik. Itu juga dapat mengembalikan objek ditangguhkan lainnya dan panggilan balik berikut akan didaftarkan pada ditangguhkan ini.Tidak demikian halnya dengan
.then()
(atau.done()
,.fail()
), nilai kembalian dari callback terdaftar hanya diabaikan.Jadi, Anda tidak menggunakan salah satu
.then()
atau.pipe()
. Kamu dapat menggunakan.pipe()
untuk tujuan yang sama.then()
tetapi sebaliknya tidak berlaku.Contoh 1
Hasil dari beberapa operasi adalah larik objek:
dan Anda ingin menghitung nilai minimum dan maksimum. Mari kita asumsikan kita menggunakan dua
done
callback:Dalam kedua kasus, Anda harus mengulang daftar dan mengekstrak nilai dari setiap objek.
Bukankah lebih baik untuk mengekstrak nilai sebelumnya sehingga Anda tidak perlu melakukan ini di kedua callback secara individual? Iya! Dan itulah yang bisa kita gunakan
.pipe()
untuk:Jelas ini adalah contoh yang dibuat-buat dan ada banyak cara berbeda (mungkin lebih baik) untuk menyelesaikan masalah ini, tapi saya harap ini menggambarkan maksudnya.
Contoh 2
Pertimbangkan panggilan Ajax. Terkadang Anda ingin memulai satu panggilan Ajax setelah panggilan sebelumnya selesai. Salah satu caranya adalah dengan melakukan panggilan kedua di dalam
done
callback:Sekarang mari kita asumsikan Anda ingin memisahkan kode Anda dan menempatkan dua panggilan Ajax ini di dalam sebuah fungsi:
Anda ingin menggunakan objek deferred untuk mengizinkan kode lain yang memanggil
makeCalls
untuk melampirkan callback untuk panggilan Ajax kedua , tapitidak akan memiliki efek yang diinginkan karena panggilan kedua dilakukan di dalam
done
panggilan balik dan tidak dapat diakses dari luar.Solusinya adalah dengan menggunakan
.pipe()
:Dengan menggunakan,
.pipe()
Anda sekarang dapat memungkinkan untuk menambahkan callback ke panggilan Ajax "dalam" tanpa menunjukkan aliran / urutan panggilan yang sebenarnya.Secara umum, objek yang ditangguhkan memberikan cara yang menarik untuk memisahkan kode Anda :)
sumber
pipe
bisa melakukan penyaringan yangthen
tidak bisa dilakukan. Tetapi dalam Googling topik-topik ini tampaknya mereka memilih untuk menyebutnyapipe
daripadafilter
karena menganggap penyaringan sebagai sesuatu dari bonus tambahan yang menyertainya sedangkanpipe
lebih jelas menunjukkan tujuan sebenarnya. Jadi sepertinya harus ada perbedaan lain selain filtering. (Kemudian lagi Aku mengakui bahwa aku tidak benar-benar memahami fitur penyaringan bahkan dengan contoh Anda Harus.result values;
Menjadireturn values;
by the way?).then()
menerima data yang sama diresult
mana Anda memfilter setiap kali; sedangkan pada contoh yang lebih rendah,.pipe()
menghapus beberapa dataresult
sebelum meneruskannya sebagairesult
dua berikutnya.then()
akan menerima?.pipe()
. Jika callback mengembalikan objek yang ditangguhkan, callback selesai atau gagal berikutnya akan didaftarkan untuk objek itu. Saya akan menyertakan contoh lain. edit: tentang komentar kedua Anda: ya.pipe()
sedangkanthen()
lebih seperti simpul daun pada akhirnya Anda harus menggunakan data Anda dan tidak mengalir lebih jauh, dan meskipun fakta bahwathen()
mengembalikanDeferred
itu tidak benar-benar digunakan / berguna? Jika ini benar, mungkin membantu untuk memperjelas untuk menyertakan sesuatu seperti/* do something with "min"/"max" */
di setiap "klausa .then ()".Tidak ada kasus di mana Anda HARUS menggunakan
then()
lebihpipe()
. Anda selalu dapat memilih untuk mengabaikan nilai yangpipe()
akan diteruskan. Mungkin ada sedikit kinerja yang menurun untuk digunakanpipe
- tetapi itu tidak menjadi masalah.Jadi sepertinya Anda selalu bisa menggunakan
pipe()
dalam kedua kasus. Namun , dengan menggunakanpipe()
, Anda berkomunikasi dengan orang lain yang membaca kode Anda (termasuk Anda sendiri, enam bulan dari sekarang) bahwa ada beberapa hal penting untuk nilai balik. Jika Anda membuangnya, Anda melanggar konstruksi semantik ini.Ini seperti memiliki fungsi yang mengembalikan nilai yang tidak pernah digunakan: membingungkan.
Jadi gunakan
then()
saat Anda harus, danpipe()
kapan Anda harus ...sumber
$(function () { $.when(getPosition()) .pipe(lookupCountry) .then(displayResults); });
"Perhatikan bahwa pipa berbeda dari lalu karena pipa mengembalikan janji baru. "Ternyata perbedaan antara
.then()
dan.pipe()
dianggap tidak perlu dan telah dibuat sama dengan jQuery versi 1.8.Dari komentar oleh
jaubourg
di tiket pelacak bug jQuery # 11010 "BUAT DEFERRED.THEN == DEFERRED.PIPE LIKE PROMISE / A":(tambang emfassis)
sumber