Baik masa depan maupun janji memblokir sampai mereka menghitung nilainya, jadi apa perbedaan di antara keduanya?
clojure
terminology
future
promise
yazz.com
sumber
sumber
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. Inisome-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:
janji
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 telahdeliver
menepati janjinya, janji tersebut tidak akan menghalangi lagi.masa depan
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.
sumber
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.sumber
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.sumber
Dalam Clojure,
promise
,future
, dandelay
adalah janji-seperti objek. Mereka semua mewakili perhitungan yang dapat ditunggu klien dengan menggunakanderef
(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 menggunakanderef
, atauforce
.promise
menawarkan fleksibilitas paling besar, karena hasilnya dikirimkan dengan cara kustom apa pun dengan menggunakandeliver
. Anda menggunakannya saat tidak adafuture
ataudelay
cocok dengan kasus penggunaan Anda.sumber
Pertama, a
Promise
adalah aFuture
. Saya rasa Anda ingin mengetahui perbedaan antara aPromise
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 AndaPromise
objek tersebut. Mirip denganFutureTask
, jika Anda mencoba mengakses hasil sebelumPromise
terpenuhi, itu akan diblokir sampai pemberi janji memenuhiPromise
. SetelahPromise
terpenuhi, Anda mendapatkan nilai yang sama selalu dan segera. Tidak sepertiFutureTask
, ada pihak lain yang terlibat di sini, yang membuatPromise
. Bahwa pihak lain bertanggung jawab untuk melakukan penghitungan dan pemenuhanPromise
.Dalam artian, a
FutureTask
adalahPromise
Anda yang dibuat untuk diri sendiri.sumber