2014-02-26 75 views
3

最近,我開發了一個使用javascript回調的新項目。我正在使用koa框架。但是,當我叫這條路線:無法在KOA中設置標題使用回調時

function * getCubes(next) { 
    var that = this; 
    _OLAPSchemaProvider.LoadCubesJSon(function(result) { 
    that.body = JSON.stringify(result.toString()); 
    }); 
} 

我得到這個錯誤:

_http_outgoing.js:331 
throw new Error('Can\'t set headers after they are sent.'); 
    ^
Error: Can't set headers after they are sent. 
at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:331:11) 
at Object.module.exports.set (G:\NAP\node_modules\koa\lib\response.js:396:16) 
at Object.length (G:\NAP\node_modules\koa\lib\response.js:178:10) 
at Object.body (G:\NAP\node_modules\koa\lib\response.js:149:19) 
at Object.body (G:\NAP\node_modules\koa\node_modules\delegates\index.js:91:31) 
at G:\NAP\Server\OlapServer\index.js:42:19 
at G:\NAP\Server\OlapServer\OLAPSchemaProvider.js:1599:9 
at _LoadCubes.xmlaRequest.success (G:\NAP\Server\OlapServer\OLAPSchemaProvider.js:1107:13) 
at Object.Xmla._requestSuccess (G:\NAP\node_modules\xmla4js\src\Xmla.js:2110:50) 
at Object.ajaxOptions.complete (G:\NAP\node_modules\xmla4js\src\Xmla.js:2021:34) 

回答

6

的問題是,你的異步調用LoadCubesJSon()需要一段時間才能恢復,但興亞沒有意識到這一點,並有繼續控制流程。這基本上就是yield

「可收益」對象包括承諾,生成器和thunk(等等)。

我個人更喜歡用'Q' library手動創建承諾。但是您可以使用任何其他承諾庫或node-thunkify來創建一個thunk。

這裏是短,但工作示例與Q

var koa = require('koa'); 
var q = require('q'); 
var app = koa(); 

app.use(function *() { 
    // We manually create a promise first. 
    var deferred = q.defer(); 

    // setTimeout simulates an async call. 
    // Inside the traditional callback we would then resolve the promise with the callback return value. 
    setTimeout(function() { 
     deferred.resolve('Hello World'); 
    }, 1000); 

    // Meanwhile, we return the promise to yield for. 
    this.body = yield deferred.promise; 
}); 

app.listen(3000); 

所以,你的代碼將如下所示:

function * getCubes(next) { 
    var deferred = q.defer(); 

    _OLAPSchemaProvider.LoadCubesJSon(function (result) { 
     var output = JSON.stringify(result.toString()); 
     deferred.resolve(output); 
    }); 

    this.body = yield deferred.promise; 
} 
+0

謝謝你loooooooooooooooooooooot!爲你解釋。你剛剛救了另一個男人的心臟;-) – wmehanna