我正在围绕Express JS创建一个抽象层,但是遇到了问题。考虑以下代码(请参阅底部),在调用registerRoute并单击该行时:
expressFnc(route, (req: any, res: any, next: any) => dummy(req, res, next));
我遇到错误:
无法读取未定义的属性“ lazyrouter”
在这种情况下,我认为“ this”适用于ExpressJS(lib / application.js:479:10)。
const express = require("express");
export class ExpressHttpHost implements IHttpHost {
private host: any = express();
private contentResolver?: ContentResolver;
public configure(contentResolver: ContentResolver): void {
this.contentResolver = contentResolver;
}
public registerRoute(
route: string,
verb: HttpVerb,
handler: (request: HttpRequest) => HttpResponse,
): void {
switch (verb) {
case HttpVerb.Get:
this.createDummyRequest(this.host.get, route, handler);
break;
case HttpVerb.Delete:
this.createDummyRequest(this.host.delete, route, handler);
break;
case HttpVerb.Options:
this.createDummyRequest(this.host.options, route, handler);
break;
case HttpVerb.Patch:
this.createDummyRequest(this.host.patch, route, handler);
break;
case HttpVerb.Post:
this.createDummyRequest(this.host.post, route, handler);
break;
case HttpVerb.Put:
this.createDummyRequest(this.host.put, route, handler);
break;
case HttpVerb.All:
this.createDummyRequest(this.host.get, route, handler);
this.createDummyRequest(this.host.delete, route, handler);
this.createDummyRequest(this.host.options, route, handler);
this.createDummyRequest(this.host.patch, route, handler);
this.createDummyRequest(this.host.post, route, handler);
this.createDummyRequest(this.host.put, route, handler);
break;
default:
throw new Error("Verb is not supported.");
}
}
public start(options: IHttpHostOptions): void {
this.host.listen(options.port ? options.port : 80);
}
private createHttpRequest(expressReq: any): HttpRequest {
return new HttpRequest(
expressReq.headers,
expressReq.params,
expressReq.body,
);
}
private createDummyRequest(expressFnc: any, route: string, handler: (request: HttpRequest) => HttpResponse): void {
const dummy = (expressReq: any, expressRes: any, next: any) => {
const httpRequest = this.createHttpRequest(expressReq);
const response = handler(httpRequest);
const responseStatus = response.status();
const responseMimeType = response.mimeType();
const responseContent = response.content(this.contentResolver);
expressRes.set("Content-Type", responseMimeType);
expressRes.status(responseStatus);
expressRes.send(responseContent);
next();
};
expressFnc(route, (req: any, res: any, next: any) => dummy(req, res, next));
}
}
答案 0 :(得分:1)
之所以会发生这种情况,是因为在将Express函数作为参数传递时会松散引用宿主对象。尝试手动将它们绑定回去。请参阅下面的开关中的绑定:
const express = require("express");
export class ExpressHttpHost implements IHttpHost {
private host: any = express();
private contentResolver?: ContentResolver;
public configure(contentResolver: ContentResolver): void {
this.contentResolver = contentResolver;
}
public registerRoute(
route: string,
verb: HttpVerb,
handler: (request: HttpRequest) => HttpResponse,
): void {
switch (verb) {
case HttpVerb.Get:
this.createDummyRequest(this.host.get.bind(this.host), route, handler);
break;
case HttpVerb.Delete:
this.createDummyRequest(this.host.delete.bind(this.host), route, handler);
break;
case HttpVerb.Options:
this.createDummyRequest(this.host.options.bind(this.host), route, handler);
break;
case HttpVerb.Patch:
this.createDummyRequest(this.host.patch.bind(this.host), route, handler);
break;
case HttpVerb.Post:
this.createDummyRequest(this.host.post.bind(this.host), route, handler);
break;
case HttpVerb.Put:
this.createDummyRequest(this.host.put.bind(this.host), route, handler);
break;
case HttpVerb.All:
this.createDummyRequest(this.host.get.bind(this.host), route, handler);
this.createDummyRequest(this.host.delete.bind(this.host), route, handler);
this.createDummyRequest(this.host.options.bind(this.host), route, handler);
this.createDummyRequest(this.host.patch.bind(this.host), route, handler);
this.createDummyRequest(this.host.post.bind(this.host), route, handler);
this.createDummyRequest(this.host.put.bind(this.host), route, handler);
break;
default:
throw new Error("Verb is not supported.");
}
}
public start(options: IHttpHostOptions): void {
this.host.listen(options.port ? options.port : 80);
}
private createHttpRequest(expressReq: any): HttpRequest {
return new HttpRequest(
expressReq.headers,
expressReq.params,
expressReq.body,
);
}
private createDummyRequest(expressFnc: any, route: string, handler: (request: HttpRequest) => HttpResponse): void {
const dummy = (expressReq: any, expressRes: any, next: any) => {
const httpRequest = this.createHttpRequest(expressReq);
const response = handler(httpRequest);
const responseStatus = response.status();
const responseMimeType = response.mimeType();
const responseContent = response.content(this.contentResolver);
expressRes.set("Content-Type", responseMimeType);
expressRes.status(responseStatus);
expressRes.send(responseContent);
next();
};
expressFnc(route, (req: any, res: any, next: any) => dummy(req, res, next));
}
}
答案 1 :(得分:0)
这个问题发生在我身上,我花了几个小时和额外的支持来解决。我的建议是好好阅读编译错误,因为它应该告诉你错误是在你的代码库中的哪个地方引起的。
就我而言,这是由
server.post(`/url/path/to/page`, myMiddleware(), MyClass.myNonExistentFunction);
在复杂的合并期间,对一个不存在的函数的引用已经悄悄进入我的代码库。
这个编译错误的部分问题是它没有命名未定义的回调——在这种情况下是“MyClass.myNonExistentFunction”。