In this lesson we will show how to handle multiple effects in a synchronous manner. Redux Saga gives us the actionChannel effect which gives us the power to queue requests.
Instructor: [00:00] Instead of our actions file, let's import actionChannel and take as well as create a new action creator called queueChannelRequest. We'll continue using fetchStarWars request as the action that will get us inside of our saga generator. We'll use queueChannelRequest as the action that will be queued up by the UI.
[00:18] Let's remove fetchPerson and make a new saga. We'll call it takeOneAtMost. We'll do const chan = yield actionChannel and a type. Then we'll create an infinite for loop that will hold three different yields. The first yield will be a take. The second will be our call method. Our third will be a put with an action creator. We'll change the data to be the index.
[00:43] Inside this saga, we're first using the actionChannel effect. ActionChannel instructs the middleware to queue up the actions that matched the provided type. Every time queueChannelRequest is dispatched, actionChannel will pick it up and begin building up a queue.
[01:00] In order to process this queue, we create this infinite loop that will stop and go with each request that's inside the queue. Don't let the infinite loop scare you because, remember, take is a blocking effect. It will stop the loop until there is something in the queue.
[01:15] Once we passed take, it will remove one stored effect from the queue. We'll be blocked again on call. Once call has returned, we will dispatch our put action creator with the current index. We do this so that we can print to the screen how many requests we've processed in this queue.
[01:32] Now we have some setup we need to do. We need to make sure that queueChannelRequest is wired up with our store, so we'll add it inside of our bindActions to dispatch.
[01:40] We need to go to our types file and make sure that our queueChannelRequest type is in there. Then, finally, we need to go to our sagas file and switch out fetchPerson with takeOneAtMost. Finally, we'll update our UI so that we can play around with our channel.
[02:00] Now add a state object with a count property. We'll make a function called handleQueue. It will call our queueChannelRequest action creator and update our state to be one more than the previous state.
[02:15] Then we'll delete our mapping inside of our div, and paste in a couple of h3s, add another button that when clicked on does the handleQueue function we just made. The first h3 is going to show us the number of times we fired our queueChannelRequest action. The second h3 will tell us how many times we've processed that action.
[02:37] If you remember, inside of our put effect we put the for loops index as the data. If our action channel is working correctly, we should be able to click on the second button very rapidly. Our channel queue should process each request one at a time until our components count state and our reducers data match.
[02:59] With our browser open, we can see our two h3s and our two buttons. This zero is our component state which shows how many times we've dispatched our queueChannelRequests. We first need to click on the "Load more" button to enter our saga. Then, as I click on the queue channel button, our local state will respond immediately. Our saga will begin to queue up our effects.
[03:21] We can see this is working correctly because the effects are first, one after another. Once one resolves, the next one begins until our two numbers match up.
How is actionChannel different from takeAll?
What is a good use case for this? For buttons, you can always disable until response returns...so curious what real world situations give rise to ActionChannel?