Frage

Kürzlich habe ich an einem neuen Projekt gearbeitet, das Javascript-Callbacks verwendet.Und ich benutzte koa Rahmen.Aber als ich diese Route anrief :

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

Ich bekomme diesen Fehler :

_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)
War es hilfreich?

Lösung

Das Problem ist, dass Ihr asynchroner Anruf LoadCubesJSon() es dauert eine Weile, bis sie zurückkehren, aber Koa ist sich dessen nicht bewusst und fährt mit dem Kontrollfluss fort.Das ist im Grunde was yield ist für.

Zu den "ertragbaren" Objekten gehören unter anderem Versprechen, Generatoren und Thunks.

Ich persönlich bevorzuge es, manuell ein Versprechen mit dem zu erstellen 'Q' Bibliothek.Sie können jedoch jede andere Versprechensbibliothek verwenden oder node-thunkify um einen Thunk zu erstellen.

Hier ist ein kurzes, aber funktionierendes Beispiel mit 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);

Ihr Code würde also wie folgt aussehen:

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;
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top