Javascript 在膝关节炎中使用NoDEJS的回调

Javascript 在膝关节炎中使用NoDEJS的回调,javascript,node.js,callback,koa,Javascript,Node.js,Callback,Koa,最近我在做一个新项目,这个项目在nodejs中使用JavaScript回调。现在我们使用ES6生成器,但当我们尝试使用ES6生成器和回调时,问题就出现了 //Calback function function load(callback){ result = null; //Do something with xmla4js and ajax callback(result); return result; } 现在,我需要调用load并向客户端响应json,所以我使用下面的代

最近我在做一个新项目,这个项目在nodejs中使用JavaScript回调。现在我们使用ES6生成器,但当我们尝试使用ES6生成器和回调时,问题就出现了

//Calback function
function load(callback){
  result = null;
  //Do something with xmla4js and ajax
  callback(result);
  return result;
}
现在,我需要调用
load
并向客户端响应json,所以我使用下面的代码:

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;
  });
}
但我得到了这个错误:

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

为了澄清问题,让我们将您的回拨写为

//Calback function
function load(callback){
    setTimeout(function() {
        var result = JSON.stringify({ 'my': 'json'});
        callback(/* error: */ null, result);
    }, 500);
}
《膝关节炎》中的p> >,称为<代码> thox< /COD>,这意味着它是一个异步函数,只需要一个参数:与原型(Err,Res)的回调。你可以找一个更好的解释

现在,您必须使用

function *loadJson(){
  this.type = 'application/json';
  this.body = yield load;
}
要绕过Koa的内置响应处理,可以显式设置
this.response=false
;。如果您想写入原始代码> RES>代码>对象,请使用此方法,而不是让膝关节炎处理您的响应。


头已经被内置的响应处理写在调用回调之前。

这主要是因为膝关节炎是基于生成器的,如果您在中间件的顶部,它不支持回调。因此,它不是等待函数完成。最好的解决方案是将您的函数转换为承诺。允诺对膝关节炎很有效。

< P>我使用脑树(正则回调)和膝关节炎(KOA)有非常相似的问题。根据您的代码,我需要做的唯一更改是加载函数及其调用方式

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

app.get('/load',loadjson);

function *loadJson(){
  this.body = yield load;
}

// Callback function
function load(callback) {
  // Prepare some data with xmla4js and ajax
  whatever_inputs = {...};
  final_method(whatever_inputs, callback);
}

上面Jerome和Evan的解释是绝对正确的,看起来是一个自动执行的合适过程。

虽然thunks是个好主意,但在我看来,
承诺
是一个更好的长期方法。许多库已经开始转向异步承诺,而不是旧的节点标准
回调(err,data)
,而且它们非常容易包装任何异步代码来做出承诺。其他开发人员将有承诺方面的经验,并且自然理解您的代码,而大多数开发人员将不得不查找“thunk”是什么

在这里我把一个没有承诺的JSODOM封装在一个承诺中,这样我就可以在膝关节炎产生器中屈服了。
const jsdom = require('node-jsdom');
const koa = require('koa');
const app = koa();
​
app.use(function *() {
  this.body = yield new Promise((resolve, reject) => jsdom.env({
    url: `http://example.org${this.url}`,
    done(errors, { document }) {
      if (errors) reject(errors.message);
      resolve(`<html>${document.body.outerHTML}</html>`);
    },
  }));
});
​
app.listen(2112);

此错误是由于多个res.send()引起的。响应已经发送,您再次尝试发送。在加载函数中,我需要ajax,因为xmla4js使用它。但我只能记录加载结果,无法发送到客户端。这个问题是膝关节炎还是XMLA4JS发生的?请注意,<代码> >。响应< /COD>不是官方膝关节炎的官方支持,而是BooKoA应用程序。我不认为这是问题的答案。你能提供一个关于这个问题的承诺的例子吗?你可以用上面的例子。选择的答案。或者,如果您愿意,您可以使用
co
const router = require('koa-router');
const { load } = require('some-other-lib');
const app = koa();
app.use(router(app));

app.get('load', loadjson);

function* loadJson() {
  this.body = yield new Promise(resolve => {
    load(result => resolve(result));
  });
}