2010-10-12 22 views
15

Olay tabanlı programlamaya oldukça yeni geliyorum (node.js kullanarak). İnanıyorum ki, bu konuda hiçbir şey yapmıyorum, çünkü tekrar tekrar ve tekrar karşılaştığım özel bir problem var. Kısacası, bu problem yolunuza çıktığı zaman uyumsuzluk ile uğraşmaktır. Bu, çoğunlukla, benim durumumda, tasarım tarafından engellenmeyen ve geri çağrı tabanlı bir API'yi teşvik eden üçüncü taraf kitaplıklarıyla çalışırken kendini gösterir.JavaScript Tasarım Kalıpları - İstenmeyen Eşzamansızlık ile Başa Çıkma

Örneğin: Şu anda mranney's node-redis library'u ağır kullanan bazı şeyler yazıyorum. Programım RSS beslemelerini kazıyarak ve sonuçları redis'e sığdırıyor.

  1. Pençe yem, feed:<feedId>:results:<timestamp> gibi bir şey bir anahtarla bir Redis karma olarak mağaza sonuçları: Ben REDIS ile ortak strateji inandığımız kullanıyorum.
  2. Referansı en son sonucu feed:<feedId>:latest altında saklayın. latest_reading fonksiyonu çıkmak için hazır sonra kadar tanımlanmamış nedeniyle
 
var redis = require("redis"); 
var client = redis.createClient(); 

var get_latest_results = function (feedId) { 
    client.get('feed:+ feedId + ':latest', function (err, res) { 
     var latest_reading_key = res.toString(); 
     client.hgetall(latest_reading_key, function (err, res) { 
      var latest_reading = res; 
     }); 
    }); 
    // how do I specify a return value for this function? 
} 

, get_latest_results fonksiyonu başarısız altındaki return latest_reading yerleştirilmesi. içine return latest_reading yerleştirme çağrı başarısız olur, çünkü return geri arama için başvuruyor ve get_latest_results tarafından yoksayılır.

Bu, yolumu sürekli yazmakta olduğum durumun sadece bir örneğidir. Belki kare çukuru yuvarlak deliğe sıkıştırmaya çalışıyorum çünkü daha iyi bilmiyorum. Bu sınıf problemlerini çözmenin haksız bir yolu olmalı.

cevap

28

Eşzamansızlık ile uğraşıyorsunuz çünkü işlevlerinizi eşzamanlı bir paradigmada yazıyorsunuz.

Eşzamansız durumunda, olaylara geri aramalar eklemelisiniz. get_latest_results() gibi eşzamansız bir işlevden sonuç beklememelisiniz, ancak sonuçlar hazır olduğunda çağrılacak bir argüman olarak bir geriçağırım işlevi iletmelisiniz. ihtiyacı ne gerekiyorsa yapacak geri arama sonuçlarınıza ile yapılması:

var get_latest_results = function (feedId, readyCallback) { 
    client.get('feed:' + feedId + ':latest', function (err, res) { 
     var latest_reading_key = res.toString(); 
     client.hgetall(latest_reading_key, function (err, res) { 
      readyCallback(res);       //--- Trigger Callback 
     }); 
    }); 
    // how do I specify a return value for this function? //--- You don't 
} 

Sonra bu gibi işlevini çağırabilirsiniz:

get_latest_results(1000, function (result) { 
    //--- Do whatever needs to be done with the latest result... 
}); 
+4

+1. Beğenmeyi öğren. 'Çünkü, JavaScript senkronize olmayan kodları senkronize olarak (ya da tam tersi) çalıştırabilmeniz için gereken iş parçacıkları ya da koroutinler gibi dil seviyesindeki ilkelleri vermez. – bobince

İlgili konular