Apa perbedaan antara Tangguhan, Janji dan Berjangka?
Apakah ada teori yang disetujui secara umum di balik ketiganya?
Apa perbedaan antara Tangguhan, Janji dan Berjangka?
Apakah ada teori yang disetujui secara umum di balik ketiganya?
Jawaban:
Mengingat ketidaksukaan yang jelas untuk bagaimana saya telah mencoba untuk menjawab pertanyaan OP. Jawaban literalnya adalah, janji adalah sesuatu yang dibagikan dengan benda lain, sementara yang ditangguhkan harus dirahasiakan. Terutama, yang ditangguhkan (yang umumnya meluas Janji) dapat menyelesaikan sendiri, sementara janji mungkin tidak dapat melakukannya.
Jika Anda tertarik dengan hal-hal kecil, maka periksa Janji / A + .
Sejauh yang saya ketahui, tujuan menyeluruh adalah untuk meningkatkan kejelasan dan melonggarkan kopling melalui antarmuka standar. Lihat saran bacaan dari @ jfriend00:
Alih-alih secara langsung meneruskan panggilan balik ke fungsi, sesuatu yang dapat mengarah ke antarmuka yang sangat erat, menggunakan janji memungkinkan seseorang untuk memisahkan masalah untuk kode yang sinkron atau tidak sinkron.
Secara pribadi, saya telah menemukan ditangguhkan sangat berguna ketika berhadapan dengan misalnya template yang diisi oleh permintaan asinkron, memuat skrip yang memiliki jaringan dependensi, dan memberikan umpan balik pengguna untuk membentuk data dengan cara yang tidak menghalangi.
Memang, bandingkan bentuk panggilan balik murni dari melakukan sesuatu setelah memuat CodeMirror dalam mode JS secara asinkron (maaf, saya tidak menggunakan jQuery untuk sementara waktu ):
/* assume getScript has signature like: function (path, callback, context)
and listens to onload && onreadystatechange */
$(function () {
getScript('path/to/CodeMirror', getJSMode);
// onreadystate is not reliable for callback args.
function getJSMode() {
getScript('path/to/CodeMirror/mode/javascript/javascript.js',
ourAwesomeScript);
};
function ourAwesomeScript() {
console.log("CodeMirror is awesome, but I'm too impatient.");
};
});
Untuk versi yang dirumuskan janji (sekali lagi, permintaan maaf, saya tidak up to date di jQuery):
/* Assume getScript returns a promise object */
$(function () {
$.when(
getScript('path/to/CodeMirror'),
getScript('path/to/CodeMirror/mode/javascript/javascript.js')
).then(function () {
console.log("CodeMirror is awesome, but I'm too impatient.");
});
});
Permintaan maaf untuk kode semi-semu, tapi saya harap itu membuat ide inti agak jelas. Pada dasarnya, dengan mengembalikan janji yang terstandarisasi, Anda dapat melewati janji itu, sehingga memungkinkan pengelompokan yang lebih jelas.
fn(callback, errback)
tidak ada yang lebih erat atau kurang bermanfaat dari fn().then(callback, errback)
- tapi itu cara yang salah untuk menggunakan janji. Saya terutama membenci $.when
contoh kultus kargo - sama sekali tidak ada alasan Anda tidak dapat memiliki $.when
fungsi yang bekerja dengan callback.
Jawaban-jawaban ini, termasuk jawaban yang dipilih, baik untuk memperkenalkan janji konseptual, tapi kurang dalam spesifik dari apa sebenarnya perbedaan dalam terminologi yang timbul ketika menggunakan perpustakaan menerapkan mereka (dan ada yang perbedaan penting).
Karena masih merupakan spec yang berkembang , jawabannya saat ini berasal dari upaya mensurvei kedua referensi (seperti wikipedia ) dan implementasi (seperti jQuery ):
Ditangguhkan : Tidak pernah dijelaskan dalam referensi populer,
1 2 3 4
tetapi umumnya digunakan oleh implementasi sebagai wasit dari resolusi janji (implementasi dan ).
5 6 7
resolve
reject
Kadang-kadang ditangguhkan juga merupakan janji (implementasi then
),
5 6
kali lain itu dianggap lebih murni untuk memiliki tangguhan hanya mampu resolusi, dan memaksa pengguna untuk mengakses janji untuk menggunakan .
7
then
Janji : Kata yang paling lengkap untuk strategi yang dibahas.
Objek proxy menyimpan hasil fungsi target yang sinkronisitasnya ingin kita abstraksi, ditambah mengekspos then
fungsi yang menerima fungsi target lain dan mengembalikan janji baru.
2
Contoh dari CommonJS :
> asyncComputeTheAnswerToEverything()
.then(addTwo)
.then(printResult);
44
Selalu dijelaskan dalam referensi populer, meskipun tidak pernah ditentukan untuk siapa tanggung jawabnya jatuh. 1 2 3 4
Selalu hadir dalam implementasi populer, dan tidak pernah diberikan resolusi resolusi. 5 6 7
Masa Depan : istilah yang tampaknya sudah ketinggalan zaman ditemukan dalam beberapa referensi populer 1 dan setidaknya satu implementasi populer, 8 tetapi tampaknya sedang dihapus dari diskusi dalam preferensi untuk istilah 'janji' 3 dan tidak selalu disebutkan dalam pengantar populer untuk topik tersebut. 9
Namun, setidaknya satu perpustakaan menggunakan istilah umum untuk abstrak sinkronisasi dan penanganan kesalahan, sambil tidak menyediakan then
fungsionalitas.
10
Tidak jelas apakah menghindari istilah 'janji' itu disengaja, tetapi mungkin pilihan yang baik karena janji dibangun di sekitar 'barang-barang luar'.
2
Perbedaan antara Janji / A dan Janji / A +
(TL; DR, Janji / A + sebagian besar menyelesaikan ambiguitas dalam Janji / A)
Task
Yang benar-benar membuat saya mengklik adalah presentasi oleh Domenic Denicola ini.
Dalam inti github , dia memberikan deskripsi yang paling saya sukai, sangat ringkas:
Inti dari janji-janji itu adalah mengembalikan komposisi fungsional dan kesalahan yang muncul di dunia async.
Dengan kata lain, janji adalah cara yang memungkinkan kita menulis kode asinkron yang hampir mudah untuk ditulis seolah-olah itu sinkron .
Pertimbangkan contoh ini, dengan janji:
getTweetsFor("domenic") // promise-returning async function
.then(function (tweets) {
var shortUrls = parseTweetsForUrls(tweets);
var mostRecentShortUrl = shortUrls[0];
return expandUrlUsingTwitterApi(mostRecentShortUrl); // promise-returning async function
})
.then(doHttpRequest) // promise-returning async function
.then(
function (responseBody) {
console.log("Most recent link text:", responseBody);
},
function (error) {
console.error("Error with the twitterverse:", error);
}
);
Ini berfungsi seolah-olah Anda sedang menulis kode sinkron ini:
try {
var tweets = getTweetsFor("domenic"); // blocking
var shortUrls = parseTweetsForUrls(tweets);
var mostRecentShortUrl = shortUrls[0];
var responseBody = doHttpRequest(expandUrlUsingTwitterApi(mostRecentShortUrl)); // blocking x 2
console.log("Most recent link text:", responseBody);
} catch (error) {
console.error("Error with the twitterverse: ", error);
}
(Jika ini masih terdengar rumit, tonton presentasi itu!)
Mengenai Ditangguhkan, itu cara .resolve()
atau .reject()
janji. Dalam spec Janji / B , itu disebut .defer()
. Di jQuery, itu $.Deferred()
.
Harap dicatat bahwa, sejauh yang saya tahu, implementasi Janji di jQuery rusak (lihat intinya), setidaknya pada jQuery 1.8.2.
Seharusnya mengimplementasikan Promises / A thenables , tetapi Anda tidak mendapatkan penanganan kesalahan yang benar, Anda harus, dalam arti bahwa seluruh fungsi "async try / catch" tidak akan berfungsi. Sangat disayangkan, karena memiliki "coba / tangkap" dengan kode async benar-benar keren.
Jika Anda akan menggunakan Janji (Anda harus mencobanya dengan kode Anda sendiri!), Gunakan Q Kris Kowal . Versi jQuery hanyalah beberapa agregator panggilan balik untuk menulis kode jQuery yang lebih bersih, tetapi tidak mengerti intinya.
Mengenai Masa Depan, saya tidak tahu, saya belum melihatnya di API apa pun.
Sunting: Pembicaraan youtube Domenic Denicola di Janji dari komentar @Farm di bawah ini.
Kutipan dari Michael Jackson (ya, Michael Jackson ) dari video:
Saya ingin Anda membakar frasa ini dalam pikiran Anda: Janji adalah nilai yang tidak sinkron .
Ini adalah deskripsi yang sangat baik: janji seperti variabel dari masa depan - referensi kelas satu untuk sesuatu yang, pada titik tertentu, akan ada (atau terjadi).
Sebuah Janji merupakan proxy untuk nilai belum tentu diketahui kapan janji itu dibuat. Hal ini memungkinkan Anda untuk mengaitkan penangan ke nilai keberhasilan akhir atau alasan kegagalan tindakan asinkron. Ini memungkinkan metode asinkron mengembalikan nilai seperti metode sinkron: alih-alih nilai akhir, metode asinkron mengembalikan janji memiliki nilai di beberapa titik di masa mendatang.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
The deferred.promise()
Metode memungkinkan fungsi asynchronous untuk mencegah kode lain dari campur dengan kemajuan atau status permintaan internal. Janji hanya memperlihatkan metode Ditangguhkan yang diperlukan untuk melampirkan penangan tambahan atau menentukan negara ( kemudian, dilakukan, gagal, selalu, pipa, kemajuan, negara dan janji ), tetapi bukan orang-orang yang mengubah negara ( tekad, tolak, beri tahu, tekad Dengan, tolak dengan, dan beri tahu ).
Jika target disediakan, deferred.promise()
akan melampirkan metode ke atasnya dan kemudian mengembalikan objek ini daripada membuat yang baru. Ini bisa berguna untuk melampirkan perilaku Janji ke objek yang sudah ada.
Jika Anda membuat Ditangguhkan, simpan referensi ke Ditangguhkan sehingga dapat diselesaikan atau ditolak di beberapa titik. Kembalikan hanya objek Janji melalui deferred.promise () sehingga kode lain dapat mendaftarkan panggilan balik atau memeriksa keadaan saat ini.
Secara sederhana kita dapat mengatakan bahwa Janji mewakili nilai yang belum diketahui di mana sebagai Tangguhan mewakili pekerjaan yang belum selesai.
promise
mewakili nilai yang belum diketahui deferred
mewakili pekerjaan yang belum selesaiJanji adalah pengganti untuk hasil yang awalnya tidak diketahui sementara ditangguhkan mewakili perhitungan yang menghasilkan nilai.
Referensi