tutorial ctx node.js callback koa

node.js - ctx - No se puede establecer el encabezado en KOA cuando se usa la devolución de llamada



koa vs express (1)

Recientemente trabajé en un nuevo proyecto que usa devoluciones de llamada de javascript. Y estaba usando el framework koa . Pero cuando llamé a esta ruta:

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

Me sale este error:

_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)


El problema es que su llamada asíncrona LoadCubesJSon() demora un tiempo en regresar, pero Koa no lo sabe y continúa con el flujo de control. Para eso es básicamente el yield .

Los objetos "fiables" incluyen promesas, generadores y thunks (entre otros).

Personalmente prefiero crear una promesa manualmente con la biblioteca ''Q'' . Pero puedes usar cualquier otra biblioteca de promesas o node-thunkify para crear un thunk.

Aquí hay un ejemplo breve pero funcional con 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);

Entonces su código se vería de la siguiente manera:

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; }