问题
I have an action creator which does an expensive calculation and dispatches an action every time the user inputs something (basically real time updating). However, if the user inputs multiple things, I don't want the prior expensive calculations to fully run. Ideally I want to be able to cancel execution of the previous calculations and just do the current one.
回答1:
There's no built-in feature to cancel a Promise in an asynchronous action. You can try manually implement cancellation if you're using AJAX requests, however, it's not possible if you're using Fetch API (there's an ongoing discussion about adding this feature here).
What I would suggest to do, however, instead of dispatching an expensive action every time a user types in something in a field, apply debouncing function to your event handling function. This function is available in many libraries:
- lodash#debounce
- underscore#debounce
This would delay dispatching an action until a certain number of milliseconds have elapsed since the last time this action was dispatched. It will drastically reduce a number of heavy asynchronous operations since the action will be dispatched, let's say, every 500ms or 1s depend on your configuration instead of on every change event.
An example of implementation with lodash:
class MyComponent extends React.Component {
constructor() {
// Create a debounced function
this.onChangeDelayed = _.debounce(this.onChange, 500);
}
onChange() {
this.props.onChange(); // Function that dispatches an action
}
render() {
return (<input type="text" onChange={this.onChangeDelayed} />);
}
}
回答2:
Another potential solution would be to make use of redux-saga. There's a very useful helper called takeLatest that seems to do what you're trying to accomplish.
来源:https://stackoverflow.com/questions/41205245/how-to-cancel-execution-of-a-previous-action-upon-a-new-action