Frage

Kürzlich arbeite ich an einem neuen Projekt und dieses Projekt verwendet JavaScript-Rückrufe in NodeJS.Jetzt verwenden wir KOA Das Problem tritt jedoch auf, wenn wir versuchen, ES6-Generatoren und Rückrufe zu verwenden.

//Calback function
function load(callback){
  result = null;
  //Do something with xmla4js and ajax
  callback(result);
  return result;
}

Jetzt in KOA Ich muss anrufen load und Antwort-JSON an den Client, also verwende ich diesen Code unten:

router= require('koa-router');
app = koa();
app.use(router(app));

app.get('load',loadjson);

function *loadJson(){
  var that = this;
  load(function(result){
    that.body = result;
  });
}

aber 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:40: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:2113:50)
at Object.ajaxOptions.complete (G:\NAP\node_modules\xmla4js\src\Xmla.js:2024:34)
War es hilfreich?

Lösung

Um die Dinge klarzustellen, schreiben wir Ihren Rückruf als

//Calback function
function load(callback){
    setTimeout(function() {
        var result = JSON.stringify({ 'my': 'json'});
        callback(/* error: */ null, result);
    }, 500);
}

In der Koa-Welt nennt man das a thunk, was bedeutet, dass es sich um eine asynchrone Funktion handelt, die nur ein Argument akzeptiert:ein Rückruf mit dem Prototyp (err, res).Du kannst nachschauen https://github.com/visionmedia/node-thunkify für eine bessere Erklärung.

Jetzt müssen Sie Ihre Middleware mit schreiben

function *loadJson(){
  this.type = 'application/json';
  this.body = yield load;
}

Andere Tipps

Dies liegt vor allem daran, dass KOA Generator basiert, wenn Sie auf der Oberseite der Middleware nicht die Rückrufe unterstützen.So wartet es nicht, dass die Funktion abgeschlossen ist.Die beste Lösung wäre, Ihre Funktion in ein Versprechen umzuwandeln.Versprechen funktioniert gut mit Koa.

Ich hatte ein sehr ähnliches Problem mit Braintree (regelmäßige Rückrufe) und Koa.Basierend auf Ihrem Code war die einzige Änderung, die ich tun musste, war mit der Ladefunktion und wie aufgerufen wurde.

generasacodicetagpre.

Die Erklärung von Jerome und Evan oben ist absolut richtig, und thunkify sieht aus wie ein geeigneter Prozessum es automatisch zu tun.

Während Thunks eine nette Idee waren, in meiner Sicht ist ein generasakodizidagcode ein besserer langfristiger Ansatz. Viele Bibliotheken bewegen sich bereits zu Versprechen für Async anstelle des alten Node-Standards Promise, und sie sind tot einfach, um jeden Async-Code um ein Versprechen umzuwickeln. Andere Devs werden Erfahrungen mit Versprechen haben und natürlich Ihren Kodex verstehen, während die meisten aufsehen müssten, was ein "Thunk" ist.

z. Hier wicke ich den nicht-noch-versprochenen Jsdom in einem Versprechen ein, damit ich es in meinem KOA-Generator ergeben kann.

generasacodicetagpre.

semantisch, Versprechen und Generatoren gehen Hand in Hand, um Async-Code wirklich zu klären. Ein Generator kann mehrmals erneut eingegeben werden und ergeben mehrere Werte, während ein Versprechen bedeutet "Ich verspreche, dass ich später einige Daten habe. Kombiniert, erhalten Sie eines der nützlichsten Dinge über KOA: Die Fähigkeit, sowohl Versprechen als auch Synchronwerte zu ergeben.

edit: Hier ist Ihr ursprüngliches Beispiel, das mit einem Versprechen eingeschlossen ist, um zurückzukehren:

generasacodicetagpre.

Um die integrierte Antwortverarbeitung von Koa zu umgehen, können Sie dies explizit festlegen this.respond = false;.Verwenden Sie dies, wenn Sie in das Raw schreiben möchten res Einspruch erheben, anstatt Koa die Antwort für Sie übernehmen zu lassen.

Der Header wird bereits durch die integrierte Antwortverarbeitung geschrieben, bevor Ihr Rückruf aufgerufen wird.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top