Skip to content

Instantly share code, notes, and snippets.

@slorber
Created April 13, 2016 15:56
Show Gist options
  • Save slorber/80f1792914694904af9c8ab6853d8143 to your computer and use it in GitHub Desktop.
Save slorber/80f1792914694904af9c8ab6853d8143 to your computer and use it in GitHub Desktop.
How to wait for burgers (response to http://jlongster.com/Two-Weird-Tricks-with-Redux)
function* displayer() {
const MaxToasts = 3;
const ToastDisplayTime = 4000;
let pendingToasts = [];
let activeToasts = [];
function* displayToast(toast) {
if ( activeToasts >= MaxToasts ) {
throw new Error("can't display more than " + MaxToasts + " at the same time");
}
activeToasts = [...activeToasts,toast];
yield put(events.toastDisplayed(toast));
yield call(delay,ToastDisplayTime);
yield put(events.toastHidden(toast));
activeToasts = _.without(activeToasts,toast);
}
function* toastRequestsWatcher() {
while ( true ) {
const event = yield take(Names.TOAST_DISPLAY_REQUESTED);
const newToast = event.data.toastData;
pendingToasts = [...pendingToasts,newToast];
}
}
function* toastScheduler() {
while ( true ) {
if ( activeToasts.length < MaxToasts && pendingToasts.length > 0 ) {
const [firstToast,...remainingToasts] = pendingToasts;
pendingToasts = remainingToasts;
yield fork(displayToast,firstToast);
// Add little delay so that 2 concurrent 2 toast requests aren't display at the same time
yield call(delay,300);
}
else {
yield call(delay,50);
}
}
}
yield [
call(toastRequestsWatcher),
call(toastScheduler)
]
}
export default function* toastSaga() {
yield [
call(watcher),
call(displayer)
]
}
@slorber
Copy link
Author

slorber commented Apr 13, 2016

This is an example on how you can build a toast system, that shows toasts for 4 seconds, can queue them, and make sure that no more than 3 toasts get displayed at the same time.

See picture of it running in production at stample.co: http://i.snag.gy/0moO6.jpg

More complex rules can be built on top of that (like for example reducing the toast display time if a lot of toasts are waiting to be displayed...)

I guess this same kind of logic can be applied to waiting for burgers. Instead of having your own code asking to "eat burger" (command/imperative), you should only dispatch that a burger has been seen (event/has-happened), and let a saga decide when it's the appropriate time to eat that burger.

See also http://stackoverflow.com/a/34623840/82609

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment