要优化响应延迟,必须在将响应发送回客户端后执行工作。但是,在发送响应后,我似乎能够获得运行代码的唯一方法是使用setTimeout
。有没有更好的办法?也许某个地方在发送响应后插入代码,或者在某处异步运行代码?
这里有一些代码。
koa = require 'koa'
router = require 'koa-router'
app = koa()
# routing
app.use router app
app
.get '/mypath', (next) ->
# ...
console.log 'Sending response'
yield next
# send response???
console.log 'Do some more work that the response shouldn\'t wait for'
答案 0 :(得分:9)
不要致电ctx.res.end()
,它是hacky并绕过koa的响应/中间件机制,这意味着你也可以只使用express。
这是正确的解决方案,我也发布到https://github.com/koajs/koa/issues/474#issuecomment-153394277
app.use(function *(next) {
// execute next middleware
yield next
// note that this promise is NOT yielded so it doesn't delay the response
// this means this middleware will return before the async operation is finished
// because of that, you also will not get a 500 if an error occurs, so better log it manually.
db.queryAsync('INSERT INTO bodies (?)', ['body']).catch(console.log)
})
app.use(function *() {
this.body = 'Hello World'
})
无需ctx.end()
所以简而言之,
function *process(next) {
yield next;
processData(this.request.body);
}
不是
function *process(next) {
yield next;
yield processData(this.request.body);
}
答案 1 :(得分:0)
我有同样的问题。
koa只有在所有中间件完成后才会结束响应(在application.js中,respond是响应中间件,它会结束响应。)
app.callback = function(){
var mw = [respond].concat(this.middleware);
var gen = compose(mw);
var fn = co.wrap(gen);
var self = this;
if (!this.listeners('error').length) this.on('error', this.onerror);
return function(req, res){
res.statusCode = 404;
var ctx = self.createContext(req, res);
onFinished(res, ctx.onerror);
fn.call(ctx).catch(ctx.onerror);
}
};
但是,我们可以通过调用response.end
函数解决问题,该函数是节点的api:
exports.endResponseEarly = function*(next){
var res = this.res;
var body = this.body;
if(res && body){
body = JSON.stringify(body);
this.length = Buffer.byteLength(body);
res.end(body);
}
yield* next;
};
答案 2 :(得分:-2)
您可以使用dim collection as new CollectionZone
'init collection
collection = cType(collection.OrderBy(Function(obj) obj.debutXMetres).ToList(), CollectionZone)
在异步任务中运行代码,就像:
setTimeout