【问题标题】:Can not set Header in KOA When using callback使用回调时无法在 KOA 中设置 Header
【发布时间】:2014-02-26 09:38:22
【问题描述】:

最近我在一个使用 javascript 回调的新项目上工作。我正在使用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)

【问题讨论】:

    标签: node.js callback koa


    【解决方案1】:

    问题是您的异步​​调用 LoadCubesJSon() 需要一段时间才能返回,但 Koa 并没有意识到这一点并继续控制流。这基本上就是yield 的用途。

    “Yieldable”对象包括承诺、生成器和 thunk(以及其他)。

    我个人更喜欢使用'Q' library 手动创建承诺。但是你可以使用任何其他的 Promise 库或 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;
    }
    

    【讨论】:

    • 谢谢你一个looooooooooooooooooooot !给你解释。你刚刚拯救了另一个人的心 ;-)
    猜你喜欢
    • 2017-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-03
    • 2014-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多