delvedor / find-my-way

A crazy fast HTTP router

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Wait for async handler to resolve

alii opened this issue · comments

Would it be possible to wait for the async handler to resolve in the following code? How could we know when the lookup is done

fmw.on('GET', '/', async (req, res, params) => {
    // Slow handler that could take some time
});

const data = await before(req, res);

// `await` awaits the async handler
await fmw.lookup(req, res);

await after(data);

Hi, the lookup function returns the result of a handler. If you return a promise in your handler, it will return from the lookup function. So yes, it will work.

ahh okay, perhaps the types are incorrect in this case as it's typed to return void:
image

Yes, there should be any type.

): void;

Would you like to send a PR to address this issue?

I can do that, but I think it actually is the correct typings after testing it:

image

Also perhaps it would be better to allow a generic with a default value rather than any?

The lookup returns a handler's result. You can return a value of any type from the handler. I'm not sure that I got your idea of generic type.

return ctx === undefined

I can do that, but I think it actually is the correct typings after testing it:

image

Also perhaps it would be better to allow a generic with a default value rather than any?

Are you sure that your handler returns a promise and not just undefined?

Ahh forgive me, I had visited a 404 route that was returning void. My mistake!

With regards to the generic, I mean to type lookup as follows:

lookup<Context, Response = any>(
      req: Req<V>,
      res: Res<V>,
      ctx?: Context
): Response;

Is there any difference between defining a type variable and using it once and inlining it?

I'm sorry I not sure I understand what you mean by that. I don't really think we need a generic for Context here as it is not really used, but Response is so it would make sense to keep that there

Can you give me an example of using a generic Response? Please make sure that the lookup function can return the result of any handler.

For sure! In my use case all of my handlers return a consistent shape of

export type HandlerResult = 
	| {success: true; data: unknown}
	| {success: false; data: {status: number; message: string}};

it would be great for me to type something as follows: https://www.typescriptlang.org/play

Right now I am doing this:
image

I'm not sure that this is a good idea. The lookup function isn't generic by itself. And to be generic you have to provide the defaultRoute with the same result type. Otherwise the lookup function will return undefined.

@mcollina What do you think?

That's fair, in my instance I am sure that all routes will return a HandlerResult. I suppose if the results varied then you wouldn't have to provide a generic at all (e.g. defaulting to any).

The reason I removed Context is simply because it was only used to type ctx, which has the same effect as just doing ctx: unknown because we don't use Context anywhere else.

Happy to hear thoughts :) ❤️

I agree with you, but technically, as I understand, removing Context can break someone's typescript code.