2013-08-21 126 views
7

Meteor中,我正在編寫一個方法,它必須檢查新文件的某個路徑的子目錄。 我首先想列出Meteor之後的子目錄,然後我child_process.exec一個簡單的bash腳本,列出自上次執行以來添加的文件。Future.wait()不能等待沒有纖維(等待Meteor.method中的另一個未來)

我有一些問題,目錄發現是異步(Error: Can't wait without a fiber)。我寫了一個同步版本,但同時使用fs.readdirfs.stat替代了它們的同步替代方案,這使我能夠發現錯誤。

下面的代碼:

function listDirs(dir, isDir){ 

    var future1 = new Future();fs.readdir(dir, function(err, files){ 

      if (err) 
       throw new Meteor.error(500, "Error listing files", err); 

      var dirs = _.map(files, function(file){ 

       var future2 = new Future(); 
       var resolve2 = future2.resolver(); 

       fs.stat(dir+file, function(err, stats){ 

        if (err) 
         throw new Meteor.error(500, "Error statting files", err); 

        if (stats.isDirectory() == isDir && file.charAt(0) !== '.') 
         resolve2(err, file); 

       }); 

       return future2; 

      }); 

      Future.wait(dirs); 

      //var result = _.invoke(dirs, 'get'); 

      future1['return'](_.compact(dirs)); 
     }); 

     return future1.wait(); 
    } 

錯誤Error: Can't wait without a fiberfuture2做。 當我註釋掉Future.wait(dirs)時,服務器不再崩潰,但是就我試圖解決這個問題而言。 :/

另一個_.map函數我在該方法的另一部分使用的函數與期貨工作正常。 (見https://gist.github.com/possibilities/3443021,我發現我的靈感)

回答

14

裹回調到Meteor.bindEnvironment,例如:

fs.readdir(dir, Meteor.bindEnvironment(function (err, res) { 
    if (err) future.throw(err); 
    future.return(res); 
}, function (err) { console.log("couldn't wrap the callback"); }); 

Meteor.bindEnvironment做了很多事情,其中​​之一就是要確保回調是在光纖上運行。

另一件可能有用的事情是var funcSync = Meteor._wrapAsync(func),它利用futures並允許用同步樣式調用一個函數(但它仍然是異步)。

觀看事件觸發考慮到這些視頻,如果你想知道更多:https://www.eventedmind.com/posts/meteor-dynamic-scoping-with-environment-variableshttps://www.eventedmind.com/posts/meteor-what-is-meteor-bindenvironment

+0

謝謝!在Meteor.bindEnvironment中包裝回調確實解決了期貨問題。 – jeroentbt