Node.js'deki vaatleri anlama


147

Anladığım kadarıyla eşzamansız kodu çağırmanın üç yolu var:

  1. Etkinlikler, örneğin request.on("event", callback);
  2. Geri aramalar, ör. fs.open(path, flags, mode, callback);
  3. Sözler

Düğüm sözü kitaplığını buldum ama anlamadım.

Birisi sözlerin ne hakkında olduğunu ve neden kullanmam gerektiğini açıklayabilir mi?

Ayrıca, neden Node.js'den kaldırıldı?


Bu makale bunu oldukça iyi açıklıyor. Node.js'de kullanılabilen bir uygulama söz konusu olduğunda, Futures
Sean Kinsey

İşte kendi söz sınıfımı oluşturmak için kullandığım harika bir dizi: Let's Make a Framework: Promises İşte jQuery ile ilgili video: blog.bigbinary.com/2011/09/03/jquery-deferred.html
Tom Winter

Yanıtlar:


91

Node.js'deki vaatler bazı işler yapmayı vaat ediyordu ve ardından başarı ve başarısızlık için ve zaman aşımlarını ele almak için yürütülecek ayrı geri çağırmalara sahipti. Node.js'deki vaatleri düşünmenin bir başka yolu da, yalnızca iki olay yayabilen yayıcılar olmalarıdır: başarı ve hata.

Sözlerle ilgili harika olan şey, onları bağımlılık zincirlerinde birleştirebilmenizdir (Söz C'yi yalnızca Söz A ve Söz B tamamlandığında yapın).

Bunları çekirdek node.js'den kaldırarak, çekirdeğin üstüne oturabilecek farklı vaat uygulamalarıyla modüller oluşturma imkanı yarattı. Bunlardan bazıları düğüm vaadi ve vadeli işlemler .


10
@weng Hayır değil.
Ivo Wetzel

98

Bu sorunun hala birçok görüşü olduğu için (benimki gibi) şunu belirtmek istedim:

  1. düğüm-vaadi bana göre oldukça ölü görünüyor (son işlem yaklaşık 1 yıl önceydi) ve neredeyse hiç test içermiyor.
  2. Vadeli işlem çok bana kabartılan görünüyor modülü ve kötü belgelenmiştir (ve adlandırma kuralları sadece kötü olduğunu düşünüyorum)
  3. Gitmenin en iyi yolu , hem aktif hem de iyi belgelenmiş olan q çerçevesi gibi görünüyor .

9
Ayrıca şunu da kontrol edin github.com/medikoo/deferred , Q ilklerden biri ve daha sonra ortaya çıkan birçok uygulamaya kesinlikle ilham veriyor, ancak maalesef çok yavaş ve bazı kısımlarda çok "teorik", bazılarıyla iyi oynamıyor gerçek dünya senaryoları
Mariusz Nowak


23
2014 güncellemesi - bluebird , bugün açık ara en hızlı ve en iyi hata ayıklama yeteneklerine sahip olandır.
Benjamin Gruenbaum

19

Söz, tabiri caizse bir operasyonun "nihai" sonuçlarını temsil eden bir "şey" dir. Burada dikkat edilmesi gereken nokta, bir şeyin ne zaman gerçekleştiğinin ayrıntılarını soyutlaması ve bir şey olduktan sonra ne olması gerektiğine odaklanmanıza izin vermesidir . Bu, temiz, bakımı yapılabilir bir kodla sonuçlanacaktır; burada bir geri arama içindeki bir geri arama içinde geri arama yapmak yerine, kodunuz aşağıdaki gibi görünecektir:

 var request = new Promise(function(resolve, reject) {
   //do an ajax call here. or a database request or whatever.
   //depending on its results, either call resolve(value) or reject(error)
   //where value is the thing which the operation's successful execution returns and
   //error is the thing which the operation's failure returns.
 });

 request.then(function successHandler(result) {
   //do something with the result
 }, function failureHandler(error) {
  //handle
 });

Sözlerin özellikleri, bir sözün

then

yöntem, verilen successHandler veya failHandler geri araması bittiğinde yerine getirilen yeni bir söz döndürmelidir. Bu, gerçekleştirilmesi gereken bir dizi eşzamansız göreviniz olduğunda vaatleri birbirine zincirleyebileceğiniz ve işlemlerin sıralanmasının, geri aramaları kullanmışsınız gibi garanti edildiği anlamına gelir. Bu nedenle, bir geri arama içindeki geri aramada bir geri aramayı iletmek yerine, zincirleme sözler içeren kod şu şekilde görünür:

var doStuff = firstAsyncFunction(url) {
                return new Promise(function(resolve, reject) {
                       $.ajax({
                        url: url,
                        success: function(data) {
                            resolve(data);
                        },
                        error: function(err) {
                             reject(err); 
                        } 
                  });
               };
doStuff
  .then(secondAsyncFunction) //returns a promise
  .then(thirdAsyncFunction); //returns a promise

Sözler ve neden süper havalı oldukları hakkında daha fazla bilgi edinmek için Domenic'in bloguna bakın: http://domenic.me/2012/10/14/youre-missing-the-point-of-promises/


12

PouchDB'nin yazarından Promises hakkındaki bu yeni eğitim muhtemelen her yerde gördüğüm en iyisidir. Size doğru kullanım kalıplarını ve hatta hala yaygın olarak kullanılan birkaç anti-kalıbı gösteren klasik çaylak hatalarını akıllıca kapsar - diğer eğitimlerde bile !!

Zevk almak!

Not: Başkaları tarafından iyi ele alındığı için bu sorunun diğer kısımlarına cevap vermedim.


Bunun için tek özürüm, sizi 4 numaralı Gelişmiş hatanın sonunda mizah okumaya zorluyor.
Tony O'Hagan

Aslında, eğitimdeki bir antipattern olduğunu iddia ettikleri kod, döngü ve koşul için yuvalanmaya ihtiyaç duyar ve önerdikleri kadar kolay düzleştirilemez.
Bergi

Gelişmiş 4 numaralı hata , çok daha fazla sayıda farklı yaklaşım kullanılarak da çözülebilir, bkz . Bir .then () zincirinde önceki vaat sonuçlarına nasıl erişebilirim? ( önerdikleri kapanış modeli çok popüler görünmüyor).
Bergi

Bu yalnızca bağlantı yanıtının bir yorum olması gerektiğini düşünüyorum. Lütfen buradaki cevabınıza o makalenin en azından ana noktalarını yazın.
Bergi

7

Mike Taulty'nin WinJS Promise kitaplığının nasıl çalıştığını anlatan, her biri on dakikadan kısa olan bir dizi videosu var .

Bu videolar oldukça bilgilendiricidir ve Mike, Promise API'nin gücünü birkaç iyi seçilmiş kod örneğiyle göstermeyi başarır.

var twitterUrl = "http://search.twitter.com/search.json?q=windows";
var promise = WinJS.xhr({ url: twitterUrl });

 promise = promise.then(
     function (xhr) {
     },
     function (xhr) {
         // handle error
     });

İstisnaların nasıl ele alınacağının ele alınması özellikle iyidir.

WinJ'lerin referanslarına rağmen, bu genel bir ilgi video serisidir, çünkü Promise API, birçok uygulamada genel olarak benzerdir.

RSVP , Promise / A + test paketini geçen hafif bir Promise uygulamasıdır. API'yi oldukça beğeniyorum çünkü stil olarak WinJS arayüzüne benziyor.

Nisan 2014 Güncellemesi

Bu arada, WinJS kitaplığı artık açık kaynak .


1
+1. Bu bana mantıklı gelen ve kullanımı sezgisel olan ilk örnek . Bir şekilde beynim bütün ayrıştırılamıyor deferredsve resolveve deferred.promise.thenve predefining promiseActionspopüler Q kütüphane belgelerinde. Node.js için bu kadar basit bir şey bilme şansınız var mı?
Redsandro

1
@noel, yukarıdaki bağlantıyı paylaştığınız için teşekkür ederiz, sözler için mükemmel bir giriş serisi ve genel yaklaşım / konu evrensel olduğu için WinJS özelliklerinin alakasız olduğuna katılıyorum.
arcseldon

Güzel örnek. Ayrıca ölü olan ilk bağlantınızı da
düzelttim

5

Vaatlerin bir başka avantajı da, hata işleme ve istisna atma ve yakalama, geri aramalarla başa çıkmaya çalışmaktan çok daha iyi olmasıdır.

Mavi kuş kütüphane uygular vaatler ve size büyük uzun yığın izleri verir çok hızlı ve yakalanmamış hataları hakkında uyarır. Ayrıca, http://bluebirdjs.com/docs/benchmarks.html'ye göre daha hızlıdır ve diğer vaat edilen kitaplıklardan daha az bellek kullanır


4

Söz tam olarak nedir?

Bir vaat, basitçe zaman uyumsuz bir işlemin sonucunu temsil eden bir nesnedir. Bir söz, aşağıdaki 3 durumdan herhangi birinde olabilir:

pending :: Bu başlangıç ​​durumudur, sözün yerine getirilmediği veya reddedildiği anlamına gelir.

yerine getirildi :: Bu, sözün yerine getirildiği anlamına gelir, sözün temsil ettiği değerin kullanıma hazır olduğu anlamına gelir.

reddedildi :: Bu, işlemlerin başarısız olduğu ve dolayısıyla vaadi yerine getiremeyeceği anlamına gelir. Eyaletler dışında, gerçekten anlamamız gereken vaatlerle ilişkili üç önemli varlık var.

  1. executor function :: executor işlevi, gerçekleştirilmesi gereken ve sonucu promise ile temsil edilen zaman uyumsuz işlemi tanımlar. Söz konusu nesne başlatılır başlatılmaz yürütmeye başlar.

  2. resol :: resolver, yürütücü işlevine iletilen bir parametredir ve yürütücünün başarılı bir şekilde çalışması durumunda, bu çözümlemeye sonucun geçilmesi denir.

  3. reject :: reject, yürütücü işlevine iletilen başka bir parametredir ve yürütücü işlevi başarısız olduğunda kullanılır. Başarısızlık nedeni reddine aktarılabilir.

Bu nedenle, bir vaat nesnesi oluşturduğumuzda, Executor, Resolve ve Reddet'i sağlamalıyız.

Referans :: Sözler


0

Yakın zamanda node.js'deki vaatleri de araştırıyorum. Bugüne kadar, hızı ve kaynak kullanımı nedeniyle when.js gitmenin yolu gibi görünüyor, ancak q.js'deki dokümantasyon bana çok daha iyi bir anlayış sağladı. Bu nedenle, konuyu anlamak için when.js'yi ancak q.js belgelerini kullanın.

Gönderen q.js github readme:

Bir işlev engellemeden bir değer döndüremez veya bir istisna atamazsa, bunun yerine bir söz döndürebilir. Bir vaat, işlevin sonunda sağlayabileceği dönüş değerini veya fırlatılan istisnayı temsil eden bir nesnedir. Bir söz, gecikmenin üstesinden gelmek için uzaktaki bir nesnenin proxy'si olarak da kullanılabilir.


0

Promise nesnesi, zaman uyumsuz bir işlemin tamamlanmasını veya başarısızlığını temsil eder.

Yani bir sözü yerine getirmek için iki bölüme ihtiyacınız var: -

1. Söz Yaratmak:

Promise yapıcısı, 2 parametresi çözümleme ve reddeden çalıştırıcı adı verilen bir işlevi kabul eder.

function example(){
   return new Promise (function(resolve , reject){   //return promise object
      if(success){
         resolve('success');  //onFullfiled
      }else{
         reject('error');     //onRejected
      }
   })
}

2. Taahhüt Sözü:

Promise nesnesinin, promise nesnelerini işlemek için 3 yöntemi vardır: -

1. Promise.prototype.catch (onRejected)

2. Promise.prototype.then (onFullfiled)

3. Promise.prototype.finally (onFullfiled, onRejected)

example.then((data) =>{
  //handles resolved data
  console.log(data); //prints success     
}).catch((err) => {
  //handles rejected error 
  console.log(err);  //prints error
})
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.