Async Actions
Sometimes your action might need to perform some work in the background asynchronously. For instance, you might want to dispatch an action that calculates some value and stores it to disk asynchronously, or another action that loads a resource from the network asynchronously and displays it in a view.
For these situations, Suas provides AsyncAction
and AsyncMiddleware
.
To use AsyncActions
you have to do the following.
- Pass the
AsyncMiddleware
when creating the store.
let store = Suas.createStore(reducer: ...,
middleware: AsyncMiddleware() + LoggerMiddleware())
val store = Suas.createStore(reducers)
.withMiddleware(AsyncMiddleware(), logger)
.build()
Store store = Suas.createStore(reducers)
.withMiddleware(new AsyncMiddleware(), logger)
.build();
Notice how we passed two middlewares. The AsyncMiddleware
, since it appears first, gets the action dispatched before the LoggerMiddleware
.
- Create an action that implements the
AsyncAction
. The recipe for anAsyncAction
looks like this
struct MyAsyncAction: AsyncAction {
func execute(getState: @escaping GetStateFunction, dispatch: @escaping DispatchFunction) {
// Dispatch some pre execution action
// Example: tell the UI to display an activiy indicator
let somePreAction = PreAction()
dispatch(somePreAction)
// Do some work on the current thread
// Or do it on the background thread
someBackgroundThreadOperation().onCompleted { someResult in
// Create some new action with the result
let action = SomeNewAction(result: someResult)
// Dispatch the action to inform the listeners about the result
dispatch(action)
}
}
}
class MyAsyncAction : AsyncAction {
override fun execute(dispatcher: Dispatcher, getState: GetState) {
// Dispatch some pre execution action
// Example: tell the UI to display an activiy indicator
val somePreAction = PreAction()
dispatcher.dispatch(somePreAction)
// Do some work on the current thread
// Or do it on the background thread
someBackgroundThreadOperation().onComplete(object : ResultHandler {
override fun onComplete(result: String) {
// Create some new action with the result
val someNewAction = SomeNewAction(result)
// Dispatch the action to inform the listeners about the result
dispatcher.dispatch(someNewAction)
}
})
}
}
class MyAsyncAction implements AsyncAction {
@Override
public void execute(Dispatcher dispatcher, GetState getState) {
// Dispatch some pre execution action
// Example: tell the UI to display an activiy indicator
PreAction somePreAction = new PreAction();
dispatcher.dispatch(somePreAction);
// Do some work on the current thread
// Or do it on the background thread
someBackgroundThreadOperation().onComplete(result -> {
// Create some new action with the result
SomeNewAction someNewAction = new SomeNewAction(result);
// Dispatch the action to inform the listeners about the result
dispatcher.dispatch(someNewAction);
});
}
}
When an AsyncAction
is dispatched to the store, the AsyncMiddleware
receives it. Upon receiving the AsyncAction
, the AsyncMiddleware
, performs the action by calling it's execute
and stop propagating it (so other middlewares and the reducer won't get the action).
In order to implement the AsyncAction
protocol, a struct/class has to implement the execute
function. This function gets called with two params:
getState
: a function that when called returns the current Store state. This function is analogous to store.state`.dispatch
: a function that dispatches the action to the store. This function is analogous to store.dispatch(action:)`.
In the execute
function we generally do the following:
- We can use
dispatch
parameter passed to dispatch actions to the store. This could be an action that tells the UI that we need to display an activity indicator for example. - We then perform an operation asynchronously. Such as loading a network resource, or writing and reading from disk asynchronously.
- When the operation is finished, we dispatch an action that updates the UI with some data. It can, for example, also tells the UI to remove the activity indicator we added before performing the asynchronous work.
What's Next
Check the search cities application example for a more detailed example on how to use AsyncActions
and the AsyncMiddleware
.
Check these three examples on how to implement AsyncAction
:
- URLSessionAsyncAction to dispatch an action performs a network request asynchronously.
- DiskReadActionCompletionBlock to dispatch an action that reads from disk asynchronously.
- DiskWriteAsyncAction to dispatch an action that writes to disk asynchronously.
Related Topics
Updated about 6 years ago