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 ( :fredbu durumda) seçtiğiniz bir değeri açıkça verdiğinizi unutmayın . Gelecek ise yaratıldığı yerde tüketiliyor. some-exprMuhtemelen 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.delivero vaat nesnesinin sonuçlarını alabilirsiniz .derefSiz hesaplamanız bitmeden sözünüzü yerine getirmeye çalışan herhangi bir öğe, siz bitirene kadar bloke edilecektir. İşiniz bittiğinde ve deliversözünüzü yerine getirdiğinizde, söz artık engellenmeyecektir.derefgelecektesiniz. 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.
futurearamanı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 promisehem ü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.
promiseuygun 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, futureve delaysö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:
futurehesaplamayı farklı bir işçi iş parçacığında başlatır. derefsonuç hazır olana kadar engellenecektir.
delayderefveya ilk müşteri kullandığında hesaplamayı tembel olarak gerçekleştirecektir force.
promisesonucu herhangi bir özel şekilde kullanılarak teslim edildiğinden en fazla esnekliği sunar deliver. Hiçbiri olmadığında futureveya delaykullanım durumunuzla eşleşmediğinde kullanırsınız.
İlk olarak, a Promisebir Future. Sanırım a Promiseve 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 Promisenesneyi verendir . Şuna benzer şekilde, FutureTasksonuca ulaşılmadan önce erişmeye çalışırsanız Promise, sözcü yerine getirene kadar bloke edilir Promise. Bir kez Promiseyerine 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, Promisekendinize yaptığınız bir şeydir .