2013-11-25 264 views
1

我爲IronRouter,爲什麼READFILE回調執行被髮送到客戶端的響應更新。鐵路由器服務器端路由的回調不工作

Router.map(
()-> 
    this.route 'readFile', 
     path: '/readFile' 
     where: 'server' 
     method: 'GET' 
     action:()-> 
     self = this 
     fs.readFile '/tmp/a.txt', (err, data)-> 
      if err 
      throw err 
      console.log(data.toString()) 
      self.response.writeHead(200, {'Content-Type': 'text/plain'}) 
      self.response.end(data) 
     console.log('response ...') 

http.js:733 
    W2049-12:04:26.781(8)? (STDERR)  throw new Error('Can\'t render headers after they are sent to the client.' 
    W2049-12:04:26.781(8)? (STDERR)   ^
    W2049-12:04:26.782(8)? (STDERR) Error: Can't render headers after they are sent to the client. 

但是,我用快遞,像這樣的工作。

exports.index = function(req, res){ 
    fs.readFile('/tmp/a.txt', function (err, data) { 
    if (err) throw err; 
    console.log(data.toString()); 
    res.send(200, data.toString()); 
    }); 
    console.log('response ...'); 
}; 

謝謝@ChristianF @Tarang使用Meteor._wrapAsync或Future都很好。當我使用自定義函數替換fs.readFile時。它採取前衝。我懷疑我定義的函數有錯誤。具體如下:

@getAccounts = (callback) -> 
query = "SELECT Id, Name, AccountNumber FROM Account" 
queryBySoql(query, (err, result)-> 
    if err 
    return console.error(err) 
    return callback(result) 
) 

我調用此鏈接:

# using Meteor 
#data = Meteor._wrapAsync(getAccounts)() 


#using Future 
waiter = Future.wrap(getAccounts)() 
data = waiter.wait() 
this.response.writeHead 200, {'Content-Type': 'text/plain'} 
this.response.end JSON.stringify(data) 

感謝所有。

+0

感謝。我知道了。 [Meteor._wrapAsync](https://www.eventedmind.com/feed/Ww3rQrHJo8FLgK7FF) – zhaoyou

回答

3

就在今天,我掙扎,就此問題。答案在我看來,流星(或者至少是鐵路路由器)並不像你期望的那樣處理異步調用。解決方案是將異步調用包裝到光纖中,這是流星用於保持編程同步的機制。

你的情況,試試這個(對不起,我不知道CoffeeScript的非常好):

var Future = Npm.require('fibers/future'); 
... 
var waiter = Future.wrap(fs.readFile); 
var data = waiter('/tmp/a.txt').wait(); 
response.writeHead(200, {'Content-Type': 'text/plain'}) 
response.end(data) 

編輯尋址除了問題。

功能裹在未來需要有一個回調作爲具有(ERR,結果)簽名的最後一個參數。試試這個:

@getAccounts = (callback) -> 
query = "SELECT Id, Name, AccountNumber FROM Account" 
queryBySoql(query, (err, result)-> 
    if err 
    return console.error(err) 
    return callback(err, result) 
) 
+0

是的,但是這個請求可能工作的很好,當其他請求發送到服務器時也會阻塞。直到當前readFile是complate .. – zhaoyou

+0

@zhaoyou這將不會阻止其他請求,因爲未來是非阻塞的。 – Akshat

+0

@Tarang對不起,你說得對。這不妨礙其他請求.. – zhaoyou

0

你可以將你的讀取文件請求的回調包裝到同一根光纖中。它不會阻止其他請求&出來相當乾淨。

readFile = Meteor_wrapAsync(fs.readFile.bind(fs)) 
data = readFile("/tmp/a.txt") 

console.log data 
@response.writeHead(200, {'Content-Type': 'text/plain'}) 
@response.end data 
return 
+0

謝謝。使用Meteor._wrapAsync或Future都可以。但是當我使用自定義函數替換fs.readFile時。它需要一些錯誤。 'waiter = Future.wrap(getAccounts)() data = waiter.wait()'OR'data = Meteor._wrapAsync(getAccounts)()'不起作用。 – zhaoyou