2011-07-10 19 views
6

Bir sınıfa aşağıdaki kodlarım var. (Bu coffeescript-- ve bir couchdb yardımcı programı için! - ama bu gerçekten bir node.js sorusudur). Düğüm 0.49 kullanarak Düğüm Yolu şeyler yapmaya çalışıyorum ve bu dosya sistemi işlemleri için eşzamansız çağrıları kullanmak anlamına gelir. İlk olarak, saçlarımı çekiyordum çünkü this.sentinel işleme sırasında birkaç kez sıfıra düşüyordu, bu yüzden orada yanlış bir şey yaptığımı biliyorum. Ama sonra daha da garip bir konuya çarptım: load_directory'de, console.log() çağrılarını görüyor musunuz? Bunu çalıştırdığımda ne zaman olacağını izleyin.Node.js ve Dosya Sistemi: bu bir yarış durumu mu?

check_sentinel: -> 
    @sentinel-- 
    if @sentinel == 0 
     @emit('designDirLoaded', @object) 

load_file: (rootdir, filename, object) -> 
    @sentinel++ 
    fname = path.join(rootdir, filename) 
    @manifest.push(fname) 
    fs.readFile fname, (err, data) => 
     object[filename] = data 
     @check_sentinel() 

load_directory: (dirpath, object) -> 
    @sentinel++ 
    fs.readdir dirpath, (err, files) => 
     for fname in files 
      console.log("X1: ", fname) 
      fs.stat path.join(dirpath, fname), (err, stats) => 
       console.log("X2: ", fname) 
       if stats.isFile() 
        @load_file(dirpath, fname, object) 
       if stats.isDirectory() 
        object[fname] = {} 
        @load_directory(path.join(dirpath, fname), object[fname]) 
     @check_sentinel() 

İşte ne olsun:

X1: memberByName.js 
X1: memberByClub.js 
X2: memberByClub.js 
X2: memberByClub.js 

Bu gerçeküstü olduğunu ve bir yarış durumu gibi bir çok görünüyor. "memberByName", load_file() için "memberByClub" u geçerek fs.stat() adresine geçirilir. Bunun nedeni, load_file()'un hemen döndüğü için, etrafta dolaştı ve dizideki bir sonraki dosya adını işlev çağrısına sundu. Ya da belirli bir kapsamdaki değerlerin sürekliliği konusunda yanlış anlaşılmam var mı?

cevap

8

Hayır, göreceğiniz şey bekleniyor. Hatırlamak zorunda olduğunuz bir şey, fs.stat'un senkronize olmamasıdır. Böylece, dış döngü (for fname in files) geri aramaların herhangi birinden fs.stat'a çağrılmadan önce döngüyü bitirir. Eğer memberByClub.js bkz neden

nedeni iki kez günlük açıklamada fname kullanmakta olduğunu, ama bu değişken fs.stat için geri arama denir zaman içerisinde değişime uğramıştır kapatılması, değil.

Doğru döngü ifadelerini almak için iç döngüyi do (fname) => ile sarabilirsiniz, ancak bence tüm sınıfla yapmaya çalıştığınız şeyi elde etmek için kodunuzu yeniden yapılandırmanız gerekir.

load_directory: (dirpath, object) -> 
    @sentinel++ 
    fs.readdir dirpath, (err, files) => 
     for fname in files 
      do (fname) => 
       console.log("X1: ", fname) 
       fs.stat path.join(dirpath, fname), (err, stats) => 
        console.log("X2: ", fname) 
        if stats.isFile() 
         @load_file(dirpath, fname, object) 
        if stats.isDirectory() 
         object[fname] = {} 
         @load_directory(path.join(dirpath, fname), object[fname]) 
     @check_sentinel() 
+0

Teşekkür ederiz. * Benim * yanlış anlaşılma kapsamı ve uyumsuzluğunun etkileşimi oldu. Komik bir şekilde müşteri tarafında programlamanın yıllardır hiç böyle bir şeye çarpmadım. Ben de 'do' operatörünü kahve arsenalime ekliyorum. –

İlgili konular