Açık sözlü inşaat antipatterni nedir ve bundan nasıl kaçınırım?

May 22 2014

Şuna benzeyen bir kod yazıyordum:

function getStuffDone(param) {           | function getStuffDone(param) {
    var d = Q.defer(); /* or $q.defer */ |     return new Promise(function(resolve, reject) {
    // or = new $.Deferred() etc.        |     // using a promise constructor
    myPromiseFn(param+1)                 |         myPromiseFn(param+1)
    .then(function(val) { /* or .done */ |         .then(function(val) {
        d.resolve(val);                  |             resolve(val);
    }).catch(function(err) { /* .fail */ |         }).catch(function(err) {
        d.reject(err);                   |             reject(err);
    });                                  |         });
    return d.promise; /* or promise() */ |     });
}                                        | }

Birisi bana buna sırasıyla " ertelenmiş antipattern " veya " Promiseyapıcı antipattern " dendiğini söyledi, bu kodun nesi kötü ve buna neden anti- model denir ?

Yanıtlar

380 BenjaminGruenbaum May 22 2014 at 17:07

Ertelenmiş antipattern (şimdi açık-inşaat antipattern) tarafından ortaya Esailija Ben ilk sözleri kullanıldığında sözler yapmak için yeni bir ortak antipattern kişidir, kendim yaptım. Yukarıdaki kodla ilgili sorun, sözler zinciri gerçeğinden yararlanılmamasıdır.

Sözler zincirlenebilir .thenve sözlerinizi doğrudan geri verebilirsiniz. Kodunuz getStuffDoneşu şekilde yeniden yazılabilir:

function getStuffDone(param){
    return myPromiseFn(param+1); // much nicer, right?
}

Sözler, eşzamansız kodu daha okunabilir hale getirmek ve bu gerçeği gizlemeden eşzamanlı kod gibi davranmakla ilgilidir. Vaatler, tek seferlik bir işlemin değeri üzerinden bir soyutlamayı temsil eder, bir programlama dilinde bir ifade veya ifade kavramını soyutlar.

Ertelenmiş nesneleri yalnızca bir API'yi vaatlere dönüştürürken ve bunu otomatik olarak yapamadığınızda veya bu şekilde daha kolay ifade edilen toplama işlevleri yazarken kullanmalısınız.

Esailija'dan alıntı yapmak:

Bu en yaygın anti-modeldir. Sözleri gerçekten anlamadığınızda ve onları yüceltilmiş olay yayıcılar veya geri çağırma aracı olarak düşündüğünüzde, bu duruma düşmek kolaydır. Özetleyelim: vaatler, eşzamansız kodun düz girinti ve bir istisna kanalı gibi eşzamanlı kodun kayıp özelliklerinin çoğunu korumasını sağlamakla ilgilidir.

142 Bergi Aug 29 2014 at 20:28

Bunun nesi var?

Ama desen işe yarıyor!

Seni şanslı. Ne yazık ki, bazı uç durumları unuttuğunuz için muhtemelen değil. Gördüğüm olayların yarısından fazlasında yazar, hata işleyiciyle ilgilenmeyi unuttu:

return new Promise(function(resolve) {
    getOtherPromise().then(function(result) {
        resolve(result.property.example);
    });
})

Diğer söz reddedilirse, bu yeni söze yayılmak yerine fark edilmeden gerçekleşecektir (burada ele alınacaktır) - ve yeni söz sonsuza kadar beklemede kalır ve bu da sızıntılara neden olabilir.

Aynı şey, geri arama kodunuzun bir hataya neden olması durumunda da olur - örneğin, bir hata resultiçermediğinde propertyve bir istisna atıldığında. Bu, ele alınmaz ve yeni sözü çözülmeden bırakır.

Bunun aksine, kullanmak .then()bu iki senaryoyu da otomatik olarak halleder ve bir hata meydana geldiğinde yeni sözü reddeder:

 return getOtherPromise().then(function(result) {
     return result.property.example;
 })

Ertelenmiş anti-model sadece kullanışsız değil, aynı zamanda hataya da açık . .then()Zincirleme için kullanmak çok daha güvenlidir.

Ama ben her şeyi hallettim!

Gerçekten mi? İyi. Bununla birlikte, özellikle iptal veya mesaj iletme gibi diğer özellikleri destekleyen bir söz kitaplığı kullanıyorsanız, bu oldukça ayrıntılı ve bol olacaktır. Ya da belki gelecekte olacak ya da kitaplığınızı daha iyi bir kitaplıkla değiştirmek mi istiyorsunuz? Bunun için kodunuzu yeniden yazmak istemeyeceksiniz.

Kitaplıkların yöntemleri ( then) yalnızca tüm özellikleri yerel olarak desteklemekle kalmaz, aynı zamanda belirli optimizasyonlara da sahip olabilirler. Bunları kullanmak muhtemelen kodunuzu daha hızlı hale getirecek veya en azından kitaplığın gelecekteki revizyonları tarafından optimize edilmesine izin verecektir.

Bundan nasıl kaçınırım?

Dolayısıyla, kendinizi manuel olarak oluştururken bulduğunuzda Promiseveya Deferredzaten var olan sözler söz konusu olduğunda, önce kitaplık API'sini kontrol edin . Ertelenmiş antipattern genellikle vaatleri [yalnızca] bir gözlemci modeli olarak gören insanlar tarafından uygulanır - ancak vaatler geri çağırmalardan daha fazlasıdır : bir araya getirilebilir olmaları gerekir. Her nezih kitaplıkta, uğraşmak istemediğiniz tüm düşük düzeyli şeylerle ilgilenen, akla gelebilecek her şekilde sözlerin bileşimi için birçok kullanımı kolay işlev vardır.

Mevcut bir yardımcı işlev tarafından desteklenmeyen yeni bir şekilde bazı vaatler oluşturma ihtiyacı duyduysanız, kaçınılmaz Ertelemeler ile kendi işlevinizi yazmak son seçeneğiniz olmalıdır. Daha özellikli bir kitaplığa geçmeyi düşünün ve / veya mevcut kitaplığınıza karşı bir hata bildirin. Bakımcısı, bileşimi mevcut işlevlerden türetebilmeli, sizin için yeni bir yardımcı işlev uygulayabilmeli ve / veya ele alınması gereken uç durumları belirlemeye yardımcı olmalıdır.