2014-02-26 32 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