Baik masa depan maupun janji memblokir sampai mereka menghitung nilainya, jadi apa perbedaan di antara keduanya?
Baik masa depan maupun janji memblokir sampai mereka menghitung nilainya, jadi apa perbedaan di antara keduanya?
Jawaban:
Menjawab dalam istilah Clojure, berikut adalah beberapa contoh dari screencast Sean Devlin :
(def a-promise (promise))
(deliver a-promise :fred)
(def f (future (some-sexp)))
(deref f)
Perhatikan bahwa di promise Anda secara eksplisit mengirimkan nilai yang Anda pilih dalam komputasi nanti ( :fred
dalam kasus ini). Di sisi lain, masa depan sedang dikonsumsi di tempat yang sama dengan tempat ia diciptakan. Ini some-expr
mungkin diluncurkan di belakang layar dan dihitung bersama-sama (pada akhirnya), tetapi jika tetap tidak dievaluasi pada saat itu diakses, blok utas sampai tersedia.
diedit untuk menambahkan
Untuk membantu membedakan lebih jauh antara janji dan masa depan, perhatikan hal berikut:
promise
. Objek promise tersebut sekarang dapat diteruskan ke utas mana pun.deliver
mendapatkan hasilnya ke objek promise tersebut.deref
memenuhi janji Anda sebelum Anda selesai menghitung akan diblokir sampai Anda selesai. Setelah Anda selesai dan Anda telah deliver
menepati janjinya, janji tersebut tidak akan menghalangi lagi.deref
adalah masa depan. Jika kalkulasi sudah selesai, Anda mendapatkan hasilnya. Jika belum selesai, Anda memblokir hingga selesai. (Agaknya jika belum dimulai, deref
artinya ia mulai dieksekusi, tetapi ini juga tidak dijamin.)Meskipun Anda bisa membuat ekspresi di masa mendatang serumit kode yang mengikuti pembuatan sebuah promise, itu meragukan yang diinginkan. Ini berarti bahwa masa depan benar-benar lebih cocok untuk penghitungan cepat dan latar belakang sementara promise benar-benar lebih cocok untuk jalur eksekusi yang besar dan rumit. Juga, janji tampaknya, dalam hal perhitungan yang tersedia, sedikit lebih fleksibel dan berorientasi pada pembuat janji yang melakukan pekerjaan dan benang lain yang menuai panen. Futures lebih berorientasi pada memulai utas secara otomatis (tanpa overhead yang jelek dan rawan kesalahan) dan melanjutkan dengan hal-hal lain sampai Anda - utas yang berasal - membutuhkan hasil.
future
panggilan bisa menyertakan N sexprs.
Baik Future dan Promise adalah mekanisme untuk mengkomunikasikan hasil komputasi asinkron dari Produser ke Konsumen.
Dalam kasus Future , komputasi ditentukan pada saat pembuatan Future dan eksekusi asinkron dimulai "ASAP". Ia juga "tahu" cara menelurkan komputasi asinkron.
Dalam kasus Promise the computation , waktu mulai dan [kemungkinan] pemanggilan asynchronous dipisahkan dari mekanisme pengiriman. Jika hasil komputasi tersedia, Produser harus memanggil deliver
secara eksplisit, yang juga berarti Produser mengontrol kapan hasil tersedia.
Untuk Promises Clojure membuat kesalahan desain dengan menggunakan objek yang sama (hasil promise
panggilan) untuk menghasilkan ( deliver
) dan mengkonsumsi ( deref
) hasil komputasi . Ini adalah dua kemampuan yang sangat berbeda dan harus diperlakukan seperti itu.
promise
. Konsumen 'jahat' jarang; tidak ada yang menghentikan Anda untuk membangun abstraksi Anda sendiri di atas janji.
(defn undeliverable-promise [] (let [p (promise)] (reify clojure.lang.IDeref (deref [_] (deref p)) clojure.lang.IBlockingDeref (deref [_ ms val] (deref p ms val)) clojure.lang.IPending (isRealized [_] (.isRealized p)) clojure.lang.IFn (invoke [_ _] nil))))
Sudah ada jawaban yang sangat bagus jadi hanya tambahkan ringkasan "cara menggunakan":
Kedua
Membuat janji atau masa depan mengembalikan referensi dengan segera. Referensi ini memblokir di @ / deref hingga hasil komputasi disediakan oleh thread lain.
Masa depan
Saat menciptakan masa depan, Anda memberikan pekerjaan sinkron yang harus diselesaikan. Ini dieksekusi di utas dari kumpulan tak terbatas khusus.
Janji
Anda tidak memberikan argumen saat membuat janji. Referensi harus diteruskan ke utas 'pengguna' lain yang akan deliver
menjadi hasilnya.
Dalam Clojure, promise
, future
, dan delay
adalah janji-seperti objek. Mereka semua mewakili perhitungan yang dapat ditunggu klien dengan menggunakan deref
(atau @
). Klien menggunakan kembali hasilnya, sehingga komputasi tidak dijalankan beberapa kali.
Mereka berbeda dalam cara penghitungan dilakukan:
future
akan memulai komputasi di thread pekerja yang berbeda. deref
akan memblokir sampai hasilnya siap.
delay
akan melakukan komputasi dengan malas, saat klien pertama menggunakan deref
, atau force
.
promise
menawarkan fleksibilitas paling besar, karena hasilnya dikirimkan dengan cara kustom apa pun dengan menggunakan deliver
. Anda menggunakannya saat tidak ada future
atau delay
cocok dengan kasus penggunaan Anda.
Pertama, a Promise
adalah a Future
. Saya rasa Anda ingin mengetahui perbedaan antara a Promise
dan aFutureTask
.
SEBUAH Future
mewakili nilai yang saat ini tidak diketahui tetapi akan diketahui di masa mendatang.
SEBUAH FutureTask
mewakili hasil komputasi yang akan terjadi di masa depan (mungkin di beberapa kumpulan thread). Ketika Anda mencoba mengakses hasilnya, jika komputasi belum terjadi, ia memblokir. Jika tidak, hasilnya segera dikembalikan. Tidak ada pihak lain yang terlibat dalam penghitungan hasil karena penghitungannya ditentukan sebelumnya oleh Anda.
A Promise
merupakan hasil yang akan diberikan oleh pihak yang berjanji kepada pihak yang dijanjikan di masa mendatang. Dalam hal ini Anda adalah yang dijanjikan dan pihak yang berjanji adalah orang yang memberi Anda Promise
objek tersebut. Mirip dengan FutureTask
, jika Anda mencoba mengakses hasil sebelum Promise
terpenuhi, itu akan diblokir sampai pemberi janji memenuhi Promise
. Setelah Promise
terpenuhi, Anda mendapatkan nilai yang sama selalu dan segera. Tidak seperti FutureTask
, ada pihak lain yang terlibat di sini, yang membuat Promise
. Bahwa pihak lain bertanggung jawab untuk melakukan penghitungan dan pemenuhan Promise
.
Dalam artian, a FutureTask
adalah Promise
Anda yang dibuat untuk diri sendiri.