-
-
Notifications
You must be signed in to change notification settings - Fork 655
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(core,utils): abortable atom #1091
Conversation
This pull request is being automatically deployed with Vercel (learn more). 🔍 Inspect: https://vercel.com/pmndrs/jotai/ABcZfcxrpWuez2fMNMmCw9X9yLBw |
This pull request is automatically built and testable in CodeSandbox. To see build info of the built libraries, click here or the icon next to each commit SHA. Latest deployment of this branch, based on commit 5474804:
|
Size Change: +990 B (+1%) Total Size: 146 kB
ℹ️ View Unchanged
|
2a87eb8
to
fbe1530
Compare
src/utils/abortableAtom.ts
Outdated
Update, | ||
Result extends void | Promise<void> | ||
>(read: Read<Value>, write?: Write<Update, Result>) { | ||
const { signal, abort } = new AbortController() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not a jotai user, so may be my comment will be irrelevant 🙏
AbortController only works with fetch and axios and may be some other libraries.
Cancellations in general affect any asynchronous behavior: browser api (timeout, interval), Promises, async/await .. I suggest supporting a mechanism that allows cancellations of all kinds, and not instantiating an abort controller at each run.
In a library I am preparing, I solved this by allowing the user's function to register any amount of abort callbacks, that are invoked either by user action or by effect cleanup.
function myStateProducer(props) {
props.onAbort(() => clearTimeout(id));
props.onAbort(() => clearInterval(id));
props.onAbort((reason) => controller.abort(reason));
}
This allows the user to easily implement cancellations of all kinds rather that relying on AbortController which isn't supported in legacy browsers.
How can we cancel atoms ? is there any abort
function provided ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As far as I understand, AbortController is a general subscriber, and has nothing to do with fetch and others. We can use it for anything. setTimeout/clearTimeout can work too. (DX-wise, not sure if it's ideal) It would be nice to have such usage in docs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please take a loot at the two following links:
https://developer.mozilla.org/en-US/docs/Web/API/AbortController
https://caniuse.com/abortcontroller
The problem with this approach is that you rely on the abort controller to stop the execution, but in fact, the execution doesn't stop. The then and finally blocks will still be executed, and it s unpredictable if they contain a setter
or a side effect.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My plan was to use signal.aborted
. It's not super nice, though. Maybe there would be better solutions. What we keep in mind is we don't often directly use promises. In most cases we just use async
functions.
I'm not sure if we are on the same page. Feel free to try your own idea. It can be AC based, or independent. We shouldn't need to change jotai core in either case.
(I feel like I'm missing some cases like complex dependency graph...
const { signal, abort } = new AbortController() | ||
return atom((get) => { | ||
const promise = read(get, { signal }) | ||
if (promise instanceof Promise) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For better support, I guess we should support thenable, not only promises.
ie:
typeof promise === 'function' and typeof promise.then === 'function'
Is this promise catched somewhere in case of rejection?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We heavily depend on instanceof Promise
everywhere. So, that means general thenable is not supported by jotai in the first place.
Do you see an actual issue with not supporting thenable?
Is this promise catched somewhere in case of rejection?
What does this mean? It is cached in store.
I may help with cancellations, but i ll need first to know how the repo and internals of jotai work. If there is any document describing them somehwere ? thanks in advance. |
I'm sure you already visited https://jotai.org. That covers mostly. Some comments in source code may help, but it will still require the understanding of public API first. |
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
ref: https://twitter.com/dai_shi/status/1513173028674617350
core doesn't depend on
AbortController
, only the one in utils does.