mirror of
https://github.com/honojs/hono.git
synced 2024-12-01 11:51:01 +01:00
perf(compose): optimize await
(#466)
Do not `await` if the handler is not promise.
This commit is contained in:
parent
9edf43c63b
commit
578833ea85
@ -11,9 +11,10 @@ export const compose = <C>(
|
||||
return (context: C, next?: Function) => {
|
||||
let index = -1
|
||||
return dispatch(0)
|
||||
|
||||
async function dispatch(i: number): Promise<C> {
|
||||
if (i <= index) {
|
||||
return Promise.reject(new Error('next() called multiple times'))
|
||||
throw new Error('next() called multiple times')
|
||||
}
|
||||
let handler = middleware[i]
|
||||
index = i
|
||||
@ -23,27 +24,41 @@ export const compose = <C>(
|
||||
if (context instanceof HonoContext && context.finalized === false && onNotFound) {
|
||||
context.res = await onNotFound(context)
|
||||
}
|
||||
return Promise.resolve(context)
|
||||
return context
|
||||
}
|
||||
|
||||
return Promise.resolve(handler(context, () => dispatch(i + 1)))
|
||||
.then((res: Response) => {
|
||||
// If handler return Response like `return c.text('foo')`
|
||||
if (res && context instanceof HonoContext) {
|
||||
context.res = res
|
||||
let res!: Response
|
||||
let isError: boolean = false
|
||||
|
||||
try {
|
||||
if (isPromise(handler)) {
|
||||
res = await handler(context, () => dispatch(i + 1))
|
||||
} else {
|
||||
res = handler(context, () => dispatch(i + 1))
|
||||
}
|
||||
} catch (err) {
|
||||
if (context instanceof HonoContext && onError) {
|
||||
if (err instanceof Error) {
|
||||
isError = true
|
||||
res = onError(err, context)
|
||||
}
|
||||
return context
|
||||
})
|
||||
.catch((err) => {
|
||||
if (context instanceof HonoContext && onError) {
|
||||
if (err instanceof Error) {
|
||||
context.res = onError(err, context)
|
||||
}
|
||||
return context
|
||||
} else {
|
||||
throw err
|
||||
}
|
||||
})
|
||||
}
|
||||
if (!res) {
|
||||
throw err
|
||||
}
|
||||
}
|
||||
|
||||
if (res && context instanceof HonoContext && (!context.finalized || isError)) {
|
||||
context.res = res
|
||||
}
|
||||
return context
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function isPromise(p: Function) {
|
||||
if (typeof p === 'function' && p.constructor.name === 'AsyncFunction') {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
@ -11,9 +11,10 @@ export const compose = <C>(
|
||||
return (context: C, next?: Function) => {
|
||||
let index = -1
|
||||
return dispatch(0)
|
||||
|
||||
async function dispatch(i: number): Promise<C> {
|
||||
if (i <= index) {
|
||||
return Promise.reject(new Error('next() called multiple times'))
|
||||
throw new Error('next() called multiple times')
|
||||
}
|
||||
let handler = middleware[i]
|
||||
index = i
|
||||
@ -23,27 +24,41 @@ export const compose = <C>(
|
||||
if (context instanceof HonoContext && context.finalized === false && onNotFound) {
|
||||
context.res = await onNotFound(context)
|
||||
}
|
||||
return Promise.resolve(context)
|
||||
return context
|
||||
}
|
||||
|
||||
return Promise.resolve(handler(context, () => dispatch(i + 1)))
|
||||
.then((res: Response) => {
|
||||
// If handler return Response like `return c.text('foo')`
|
||||
if (res && context instanceof HonoContext) {
|
||||
context.res = res
|
||||
let res!: Response
|
||||
let isError: boolean = false
|
||||
|
||||
try {
|
||||
if (isPromise(handler)) {
|
||||
res = await handler(context, () => dispatch(i + 1))
|
||||
} else {
|
||||
res = handler(context, () => dispatch(i + 1))
|
||||
}
|
||||
} catch (err) {
|
||||
if (context instanceof HonoContext && onError) {
|
||||
if (err instanceof Error) {
|
||||
isError = true
|
||||
res = onError(err, context)
|
||||
}
|
||||
return context
|
||||
})
|
||||
.catch((err) => {
|
||||
if (context instanceof HonoContext && onError) {
|
||||
if (err instanceof Error) {
|
||||
context.res = onError(err, context)
|
||||
}
|
||||
return context
|
||||
} else {
|
||||
throw err
|
||||
}
|
||||
})
|
||||
}
|
||||
if (!res) {
|
||||
throw err
|
||||
}
|
||||
}
|
||||
|
||||
if (res && context instanceof HonoContext && (!context.finalized || isError)) {
|
||||
context.res = res
|
||||
}
|
||||
return context
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function isPromise(p: Function) {
|
||||
if (typeof p === 'function' && p.constructor.name === 'AsyncFunction') {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
@ -1033,7 +1033,7 @@ describe('Both two middleware returning response', () => {
|
||||
const res = await app.request('http://localhost/')
|
||||
expect(res).not.toBeNull()
|
||||
expect(res.status).toBe(200)
|
||||
expect(await res.text()).toBe('Foo')
|
||||
expect(res.headers.get('content-type')).toBe('text/html; charset=UTF-8')
|
||||
expect(await res.text()).toBe('Bar')
|
||||
expect(res.headers.get('content-type')).toBe('text/plain; charset=UTF-8')
|
||||
})
|
||||
})
|
||||
|
Loading…
Reference in New Issue
Block a user