graphql / dataloader

DataLoader is a generic utility to be used as part of your application's data fetching layer to provide a consistent API over various backends and reduce requests to those backends via batching and caching.
MIT License
12.83k stars 510 forks source link

Ever considered the use of `queueMicrotask`? #348

Open andreyvital opened 1 year ago

andreyvital commented 1 year ago

It's available as of v11—isn't it better than process.nextTick? https://nodejs.org/api/globals.html#queuemicrotaskcallback

https://github.com/graphql/dataloader/blob/d336bd15282664e0be4b4a657cb796f09bafbc6b/src/index.js#L239-L255

Just a question...

Thanks, A.

victorandree commented 9 months ago

@andreyvital I had the same thought when considering this library on something like Cloudflare Workers or Vercel (see #341).

I decided to investigate and TL;DR is that I don't think queueMicrotask can quite replicate the behavior of process.nextTick(fn) because of subtle differences in scheduling. This behavior is covered by this test: https://github.com/graphql/dataloader/blob/55c33d480cdf429a0b24cf607ddd0e892521a35b/src/__tests__/dataloader.test.js#L1004C5-L1025C5.

My understanding is this: The batch is constructed, and schedules its post-promise job, before the promises to return values are constructed. This means that the associated microtask would always be queued before those promises start resolving. I don't see a way to use the queueMicrotask to schedule its job "after" Promises. setTimeout (and setImmediate, though that's deprecated) will execute after, which is why they're the backup for process.nextTick.