Ertelemeler, Vaatler ve Vadeli İşlemler arasındaki farklar nelerdir?
Bu üçünün arkasında genel olarak onaylanmış bir teori var mı?
Ertelemeler, Vaatler ve Vadeli İşlemler arasındaki farklar nelerdir?
Bu üçünün arkasında genel olarak onaylanmış bir teori var mı?
Yanıtlar:
OP'nin sorusuna nasıl cevap vermeye çalıştığımdan hoşlanmıyorum. Gerçek cevap, bir vaat diğer nesnelerle paylaşılan bir şeydir, ertelenmiş bir özel tutulmalıdır. Öncelikle, ertelenen (genellikle Vaat'i uzatan) kendini çözebilir, ancak bir söz bunu yapamayabilir.
Minutiae ile ilgileniyorsanız Promises / A + ' yı inceleyin .
Bildiğim kadarıyla, kapsayıcı amaç, standartlaştırılmış bir arayüz aracılığıyla netliği artırmak ve bağlantıyı gevşetmektir. @ Jfriend00 tarafından önerilen okumaya bakın :
Geri çağrıları işlevlere doğrudan iletmek yerine, sıkıca bağlanmış arabirimlere yol açabilecek bir şey, vaatler kullanarak, senkron veya asenkron kod için endişeleri ayırmaya izin verir.
Şahsen, özellikle eşzamansız istekler tarafından doldurulmuş şablonlar, bağımlılık ağlarına sahip komut dosyaları yükleme ve engelleme olmayan bir şekilde veri oluşturmak için kullanıcı geri bildirimi sağlama gibi ertelenmiş buldum.
Gerçekten, JS modunda CodeMirror'ı eşzamansız olarak yükledikten sonra bir şey yapmanın saf geri arama formunu karşılaştırın (özür dilerim, bir süredir jQuery kullanmadım ):
/* 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.");
};
});
Formüle edilmiş vaatlere (tekrar, özür dilerim, jQuery'de güncel değilim):
/* 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.");
});
});
Yarı sahte kod için özür dilerim, ama umarım temel fikri biraz açıklığa kavuşturur. Temel olarak, standartlaştırılmış bir söz vererek, sözün etrafından geçerek daha net bir gruplamaya izin verebilirsiniz.
fn(callback, errback)
daha sıkı bir şekilde bağlanmış veya daha az kullanışlı değil fn().then(callback, errback)
- ama yine de vaatleri kullanmanın yanlış bir yolu. Özellikle kargo kült $.when
örneğinden nefret ediyorum - $.when
geri aramalarla çalışan bir işleve sahip olmamanız için hiçbir neden yok .
Seçilen cevap dahil bu cevaplar, kavramsal olarak vaat tanıtan, ancak tam olarak farklılıklar (ve onları orada uygulayan kütüphaneleri kullanırken oluşan terminolojisinde ne özelliklerini eksik için iyidir vardır önemli farklılıklar).
Hala gelişen bir özellik olduğundan, cevap şu anda hem referansları ( wikipedia gibi ) hem de uygulamaları ( jQuery gibi) incelemeye çalışmaktan geliyor :
Ertelenmiş : Asla popüler referanslarda tarif edilmemiştir,
1 2 3 4
ancak uygulamalarda söz verilen kararın hakemidir (uygulama ve ).
5 6 7
resolve
reject
Bazen ertelemeler de söz verir (uygular then
),
5 6
kez daha ertelenmiş olanların yalnızca çözümleme yeteneğine sahip olması ve kullanıcıyı kullanma vaadine erişmeye zorlaması daha saf görülür .
7
then
Promise : Tartışılan strateji için en kapsamlı kelime.
Eşzamanlılığını soyutlamak istediğimiz bir hedef fonksiyonun sonucunu saklayan ve then
başka bir hedef fonksiyonu kabul eden ve yeni bir söz veren bir fonksiyonu ortaya koyan bir proxy nesnesi .
2
CommonJS'den bir örnek :
> asyncComputeTheAnswerToEverything()
.then(addTwo)
.then(printResult);
44
Sorumluluk çözümüne kimin düştüğü konusunda hiçbir zaman belirtilmemesine rağmen, daima popüler referanslarda açıklanmaktadır. 1 2 3 4
Her zaman popüler uygulamalarda bulunun ve asla çözünürlük yetenekleri verilmedi. 5 6 7
Gelecek : Bazı popüler referanslarda 1 ve en az bir popüler uygulamada bulunan, görünüşte onaylanmamış bir terim , 8, ancak görünüşe göre 'söz' 3 terimini tercih ederek tartışmanın aşamalı olarak kaldırıldığı ve konuyla ilgili popüler tanıtımlarda her zaman belirtilmedi. 9
Bununla birlikte, en az bir kütüphane terimi, then
işlevselliği sağlamazken eşzamanlılığı ve hata işlemeyi soyutlamak için genel olarak bu terimi kullanır .
10
'Vaat' teriminden kaçınmanın kasıtlı olup olmadığı belirsizdir, ancak vaatler 'kiralanabilirler' etrafında kurulduğundan muhtemelen iyi bir seçimdir.
2
Vaatler / A ve Vaatler / A + arasındaki fark
(TL; DR, Promises / A + çoğunlukla Promises / A'daki belirsizlikleri giderir)
Task
Gerçekten benim için tıklamayı sağlayan şey Domenic Denicola'nın bu sunumuydu.
Bir github özünde , en çok sevdiğim açıklamayı verdi, çok özlü:
Vaatlerin amacı bize async dünyasında fonksiyonel kompozisyon ve hata köpürmesini geri vermektir.
Diğer bir deyişle, vaatler, sanki senkronize gibi yazmak kadar kolay olan eşzamansız kod yazmamızı sağlayan bir yoldur .
Bu örneği, sözlerle düşünün:
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);
}
);
Bu senkron kodu yazıyormuşsunuz gibi çalışır:
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);
}
(Bu hala karmaşık görünüyorsa, o sunumu izleyin!)
Ertelenmiş ile ilgili olarak, bir yol .resolve()
ya da .reject()
vaat ediyor. Gelen Sözler / B spec, denir .defer()
. JQuery'de$.Deferred()
.
Bildiğim kadarıyla, jQuery'deki Promise uygulamasının en azından jQuery 1.8.2 itibariyle bozulduğunu (bu özete bakın) unutmayın.
Sözde uygular vaatler / A sonradan uygular , ancak tüm "async try / catch" işlevselliğinin çalışmadığı anlamında doğru hata işlemeyi almazsınız. Yazık ki, zaman uyumsuz kod ile bir "dene / yakala" sahip olmak tamamen serin.
Promises kullanacaksanız (bunları kendi kodunuzla denemelisiniz!) Kris Kowal'ın Q'sunu . JQuery sürümü, temiz jQuery kodu yazmak için sadece bazı geri çağrı toplayıcıdır, ancak noktayı kaçırır.
Gelecek ile ilgili hiçbir fikrim yok, bunu herhangi bir API'da görmedim.
Edit: Domenic Denicola'nın Youtube sözleri @Farm'dan gelen sözler aşağıda un yorumunu.
Videodan Michael Jackson'dan bir alıntı (evet, Michael Jackson ):
Bu cümleyi aklınızda yakmanızı istiyorum: Bir söz, eşzamansız bir değerdir .
Bu mükemmel bir tanımdır: bir söz gelecekten gelen bir değişken gibidir - bir noktada var olan (veya gerçekleşecek) bir şeye birinci sınıf bir referans.
Bir Söz , söz verildiğinde mutlaka bilinmeyen bir değerin proxy'sidir. İşleyicileri, eşzamansız bir eylemin nihai başarı değeri veya başarısızlık nedeniyle ilişkilendirmenize olanak tanır. Bu, eşzamansız yöntemlerin eşzamanlı yöntemler gibi değerleri döndürmesini sağlar: asenkron değer yerine, eşzamansız yöntem gelecekte bir noktada bir değere sahip olma vaadini döndürür.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
deferred.promise()
Yöntem zaman uyumsuz bir işlev iç talebin ilerlemesi veya duruma müdahale başka kod önlemek için izin verir. Promise, yalnızca ek işleyiciler eklemek veya durumu belirlemek için gereken Ertelenmiş yöntemleri ortaya çıkarır ( daha sonra, tamamlandı, başarısız oldu, her zaman, boru, ilerleme, durum ve vaat ), ancak durumu değiştirenleri ( çözme, reddetme, bildirme, çözme, rejectWith ile ve bildirWith ).
Hedef sağlanırsa, deferred.promise()
yöntemleri ona ekler ve ardından yeni bir tane oluşturmak yerine bu nesneyi döndürür. Bu, Vaat davranışını zaten var olan bir nesneye eklemek için yararlı olabilir.
Bir Erteleme oluşturuyorsanız, bir noktada ertelenebilmesi veya reddedilebilmesi için Ertelenmiş'e bir referans tutun. Diğer kodun geri çağrıları kaydedebilmesi veya geçerli durumu inceleyebilmesi için yalnızca Promise nesnesini deferred.promise () yoluyla döndürün.
Bir Sözün , Ertelenmiş olarak henüz bitmemiş bir işi temsil ettiği yerde henüz bilinmeyen bir değeri temsil ettiğini söyleyebiliriz .
promise
, henüz bilinmeyen bir değeri temsil eder deferred
henüz bitmemiş bir işi temsil ederBir erteleme, başlangıçta bilinmeyen bir sonuç için yer tutucudur, ertelenmiş ise değerle sonuçlanan hesaplamayı temsil eder.
Referans