4 ms·
Yes there was a whole discussion in a github issue about the correct pattern to solve this. Creating and guarding against a `isMounted` field in your `.then()`
by Guillaume86 9y ago
Yes there was a whole discussion in a github issue about the correct pattern to solve this. Creating and guarding against a `isMounted` field in your `.then()` callbacks means you prevent garbage collection of the unmounted components. An easy solution is to use cancellable promises (with some subtleties to allow garbage collection). There's an implementation which take care of this properly here (provides an HoC): https://github.com/hjylewis/trashable-react https://github.com/hjylewis/trashable-react .
- loevborg 9y agoWhen you say "cancellable promises", that means that you cannot use native JS promises, correct?
- Guillaume86 9y agoYou can, you just need to wrap it when used inside a react component.
- drdaeman 9y agoHow? I've thought it's just technically impossible (no API to do so) to cancel a `fetch` request in progress.
- myhf 9y agoYou don't have to cancel the fetch request, you just have to cancel its callback.
- Guillaume86 9y agoWe're talking about several different things: Native promises do not have a "real" cancellation API (no 3rd path besides resolved and rejected) but you can mimic the functionality by rejecting with a dedicated error type, or use another promise as a cancellation token for example. fetch(), which uses promises as return type, do not support aborting requests, as discussed [here](https://github.com/whatwg/fetch/issues/447 https://github.com/whatwg/fetch/issues/447) but the [old XMLHttpRequest does](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/abort https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequ...). Aborting is specific to HTTP requests, it's stopping the connection to the remote server (so technically impossible to implement with the current APIs as you said). Cancelling a promise is just stopping all onResolved continuations to be called, so it can be implemented in several different ways as I explained above. The end result if you use a classic cancellation wrapper on a fetch() promise is that the onReject continuations will be called immediately with a specific reason. The HTTP request will continue to the end (no abort), but the response will be ignored. In the case of the react library I mentioned, both the onResolved and onReject continuations will be ignored if cancelled, it's the subtlety that allows the component to be garbage collected (and probably why the author decided to call that "thrashable" as opposed to "cancellable" to mark the difference).
- always_good 9y agoFor example, you can wrap a promise such that when it finally resolves, it checks an isCancelled flag and rejects instead so that your .then callbacks aren't run. It's not about cancelling any potential inflight action within the promise itself. In this case, you don't want the callback to run after the react component unmounts, nor do you want to hold a reference to the component: promise .then(value => this.setState({ value }))
- rounce 9y agoPromises? Cancellation? The whole point of a Promise is that it must resolve to something eventually.
- ryanbrunner 9y agoYou're cancelling the promise from the perspective of the caller, not the Promise itself. Promises themselves can't decide that they don't want to resolve, but there's plenty of cases where whoever requested the promise in the first place is no longer interested in the results.