以下为ChatGPT自动生成的解答,正确与否请自行判断。
BFE.devAI解答 - JavaScript 代码题
53. 实现middleware
实现如下:
type Request = object
type NextFunc = (error?: any) => void
type MiddlewareFunc = (req: Request, next: NextFunc) => void
type ErrorHandler = (error: Error, req: Request, next: NextFunc) => void
class Middleware {
private funcs: Array<MiddlewareFunc | ErrorHandler> = []
use(func: MiddlewareFunc | ErrorHandler) {
this.funcs.push(func)
}
private trigger(index: number, req: Request, error?: Error) {
if (error) {
const errorHandler = this.funcs.find(func => func.length === 3) as ErrorHandler | undefined
if (errorHandler) {
errorHandler(error, req, (err?: any) => this.trigger(index+1, req, err))
} else {
console.log(error)
}
} else {
const func = this.funcs[index]
if (func) {
func(req, (err?: any) => this.trigger(index+1, req, err))
}
}
}
start(req: Request) {
this.trigger(0, req)
}
}
const middleware = new Middleware()
middleware.use((req, next) => {
req.a = 1
next()
})
middleware.use((req, next) => {
req.b = 2
next()
})
middleware.use((req, next) => {
console.log(req)
})
middleware.start({})
// {a: 1, b: 2}
const middlewareWithError = new Middleware()
middlewareWithError.use((req, next) => {
req.a = 1
throw new Error('sth wrong')
})
middlewareWithError.use((req, next) => {
req.b = 2
})
middlewareWithError.use((req, next) => {
console.log(req)
})
middlewareWithError.use((error, req, next) => {
console.log(error)
console.log(req)
})
middlewareWithError.start({})
// Error: sth wrong
// {a: 1}
思路是将函数放入 funcs
数组中,使用 trigger
方法按顺序执行每个函数,如果其中一个函数传入了第一个参数为 Error 的 next()
方法,就立即停止执行当前函数,直接执行 ErrorHandler 函数。如果 funcs
数组中没有 ErrorHandler 函数,直接将 error 打印出来。否则根据顺序一个一个执行。开始的时候 index 为 0,即从头开始执行。每次 next()
时,更新 index 参数并传入下一个函数。函数执行完毕返回即可。