Hem vadeli işlemler hem de vaatler, değerlerini hesaplayana kadar bloke olur, peki aralarındaki fark nedir?
Hem vadeli işlemler hem de vaatler, değerlerini hesaplayana kadar bloke olur, peki aralarındaki fark nedir?
Yanıtlar:
Clojure terimleriyle yanıtlayarak, Sean Devlin'in ekran video kaydından bazı örnekler :
(def a-promise (promise))
(deliver a-promise :fred)
(def f (future (some-sexp)))
(deref f)
Taahhütte, daha sonraki bir hesaplamada ( :fred
bu durumda) seçtiğiniz bir değeri açıkça verdiğinizi unutmayın . Gelecek ise yaratıldığı yerde tüketiliyor. some-expr
Muhtemelen perde arkasında başlatılan ve tandem (sonunda) hesaplanan, ancak zamanla unevaluated kalırsa mevcut olana kadar o iplik blokları erişilir edilir.
eklemek için düzenlendi
Bir vaat ile gelecek arasında daha fazla ayrım yapmaya yardımcı olmak için aşağıdakilere dikkat edin:
promise
. Bu vaat nesnesi artık herhangi bir iş parçacığına aktarılabilir.deliver
o vaat nesnesinin sonuçlarını alabilirsiniz .deref
Siz hesaplamanız bitmeden sözünüzü yerine getirmeye çalışan herhangi bir öğe, siz bitirene kadar bloke edilecektir. İşiniz bittiğinde ve deliver
sözünüzü yerine getirdiğinizde, söz artık engellenmeyecektir.deref
gelecektesiniz. Hesaplama zaten tamamlandıysa, sonuçlarını alırsınız. Zaten tamamlanmadıysa, tamamlanana kadar bloke edersiniz. (Muhtemelen henüz başlamamışsa, deref
çalışmaya başlaması anlamına gelir, ancak bu da garanti edilmez.)Eğer iken olabilir bir söz oluşturulmasını aşağıdaki kodu gibi karmaşık gelecekte ifadesini yapmak, 's arzu şüphelidir. Bu, vadeli işlemlerin hızlı, arka planda yapılabilen hesaplamalar için gerçekten daha uygun olduğu, vaatlerin ise büyük, karmaşık yürütme yollarına gerçekten daha uygun olduğu anlamına gelir. Mevcut hesaplamalar açısından da vaatler biraz daha esnek ve işi yapan vaat yaratan kişiye ve hasadı biçen başka bir iş parçacığına yönelik görünüyor. Vadeli işlemler, otomatik olarak bir iş parçacığı başlatmaya (çirkin ve hataya açık genel giderler olmadan) ve siz - başlangıçtaki iş parçacığı - sonuçlara ihtiyacınız olana kadar başka şeylerle devam etmeye yöneliktir.
future
aramanın gövdesi N sexpr içerebilir.
Hem Gelecek hem de Vaat, zaman uyumsuz hesaplamanın sonucunu Üretici'den Tüketiciye / Tüketicilere iletmek için kullanılan mekanizmalardır . Gelecek
durumunda , hesaplama Gelecek oluşturma sırasında tanımlanır ve zaman uyumsuz yürütme "ASAP" başlar. Aynı zamanda eşzamansız bir hesaplamanın nasıl başlatılacağını da "bilir". Promise
durumunda , hesaplama , başlangıç zamanı ve [olası] eşzamansız çağrı dağıtım mekanizmasından ayrıştırılır. Hesaplama sonucu mevcut olduğunda , Üretici bunu açıkça aramalıdır, bu aynı zamanda Üreticinin sonucun ne zaman hazır olduğunu kontrol edeceği anlamına gelir. deliver
İçin Promises Clojure aynı nesneyi (sonucu kullanarak bir tasarım hata yaptığında promise
hem üretmek () çağrısından deliver
) ve tüketmek ( deref
) sonucu hesaplama . Bunlar çok farklı iki yetenektir ve bu şekilde ele alınmalıdır.
promise
uygun olup olmayacağından emin değilim . "Kötü" tüketiciler nadirdir; Hiçbir şey sizi vaatler üzerine kendi soyutlamanızı inşa etmekten alıkoyamaz.
(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))))
Zaten mükemmel yanıtlar var, bu nedenle yalnızca "nasıl kullanılır" özetini ekleyerek:
Her ikisi de
Söz veya gelecek yaratmak, hemen bir referans verir. Bu referans, hesaplamanın sonucu başka bir iş parçacığı tarafından sağlanana kadar @ / deref üzerinde engeller.
Gelecek
Geleceği yaratırken, senkronize bir işin yapılmasını sağlarsınız. Adanmış sınırsız havuzdan bir iş parçacığında yürütülür.
Söz vermek
Söz verirken hiçbir argüman vermiyorsunuz. Referans deliver
, sonuçlanacak diğer 'kullanıcı' dizisine aktarılmalıdır .
Clojure yılında promise
, future
ve delay
söz benzeri nesneler vardır. Hepsi, istemcilerin deref
(veya @
) kullanarak bekleyebilecekleri bir hesaplamayı temsil eder . İstemciler sonucu yeniden kullanır, böylece hesaplama birkaç kez çalıştırılmaz.
Hesaplamanın gerçekleştirilme biçiminde farklılık gösterirler:
future
hesaplamayı farklı bir işçi iş parçacığında başlatır. deref
sonuç hazır olana kadar engellenecektir.
delay
deref
veya ilk müşteri kullandığında hesaplamayı tembel olarak gerçekleştirecektir force
.
promise
sonucu herhangi bir özel şekilde kullanılarak teslim edildiğinden en fazla esnekliği sunar deliver
. Hiçbiri olmadığında future
veya delay
kullanım durumunuzla eşleşmediğinde kullanırsınız.
İlk olarak, a Promise
bir Future
. Sanırım a Promise
ve a arasındaki farkı bilmek istiyorsunuz FutureTask
.
A Future
, şu anda bilinmeyen ancak gelecekte bilinecek bir değeri temsil eder.
A FutureTask
, gelecekte gerçekleşecek bir hesaplamanın sonucunu temsil eder (belki bir iş parçacığı havuzunda). Sonuca erişmeye çalıştığınızda, hesaplama henüz gerçekleşmediyse, bloke olur. Aksi takdirde sonuç hemen iade edilir. Hesaplama önceden sizin tarafınızdan belirtildiğinden, sonucun hesaplanmasına dahil olan başka bir taraf yoktur.
A Promise
, gelecekte söz verene vaat edene iletilecek bir sonucu temsil eder. Bu durumda siz söz verensiniz ve söz veren de size Promise
nesneyi verendir . Şuna benzer şekilde, FutureTask
sonuca ulaşılmadan önce erişmeye çalışırsanız Promise
, sözcü yerine getirene kadar bloke edilir Promise
. Bir kez Promise
yerine getirildiğinde, her zaman ve anında aynı değeri alırsınız. A'dan farklı olarak FutureTask
, burada başka bir taraf daha var, biri Promise
. Hesaplamanın yapılmasından ve yerine getirilmesinden başka bir tarafın sorumlu olduğunu Promise
.
Bu anlamda a FutureTask
, Promise
kendinize yaptığınız bir şeydir .