question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Async actions appear to be out of order

See original GitHub issue

I’m trying to use async actions. For simplicity, I’m using only a single action, called update, and dispatching all app actions through that. I’m also using the load and update events to set a state value on app startup and print the value on every state change, respectively.

Here’s the code:

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>Hyperapp Async Test</title>
  </head>

  <body id="root">
    <script src="https://unpkg.com/hyperapp"></script></script>

    <script>
var { app, h } = hyperapp;
var initModel = 0;

// Helper to create an action payload in the correct shape.
function payload(key, value) { return { key: key, value: value }; }

function view(state, { update }) {
  return h("div", {}, [
    h("p", {}, "Current value: " + state.model),

    h("button",
      { onclick: _ => update(payload("increment")) },
      "Increment") ]);
}

function update(state, _, payload) {
  return function(update2) {
    switch (payload.key) {
      case "edit":
        return Promise.resolve({ model: payload.value }).then(update2);

      case "increment":
        return Promise.resolve({ model: state.model + 1 }).then(update2);

      case "log":
        console.log(payload.value);
        return Promise.resolve(state).then(update2);
    }
  };
}

var events = {
  load: function(_, { update }) {
    // Set the value to 5 when the app loads.
    return update(payload("edit", 5));
  },

  update: function(_, { update }, nextState) {
    // Log the value whenever it changes.
    return update(payload("log", nextState));
  }
};

app({
  state: { model: initModel },
  view: view,
  actions: { update: update },
  events: events
});
    </script>
  </body>
</html>

I’m having two problems:

  1. State updates appear out of order. First state is { model: 5 }, then it’s { model: 0 }, while my understanding is it should be the other way round.

  2. State seems to become { model: undefined } after the load event fires, so the view renders as Current value: undefined, and clicking the Increment button logs Object { model: NaN }.

Any suggestions on fixing these async updates? Thanks

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Comments:6 (2 by maintainers)

github_iconTop GitHub Comments

1reaction
jorgebucarancommented, Sep 16, 2017

@yawaramin will force a state update even if the state value hasn’t changed

How could we determine if the state changed or not? We could check if appState holds the same reference or if it’s a new reference, and if it’s the same skip the update, already talked about here and the consensus was to let you have it.

0reactions
yawaramincommented, Sep 16, 2017

OK, I figured it out. The key is something similar to what @andyrj said–instead of returning a call to update with the existing state from the "log" case, I changed it to return undefined. It seems that the update function in async updates (which I called update2 above to avoid ambiguity) will force a state update even if the state value hasn’t changed. In turn, this will trigger my update event handler, which will call the update action, which will force a state update again, and so on, ad infinitum. Neat little infinite loop.

TL;DR: avoid potential infinite loop by not calling the async update function if the state hasn’t actually changed.

Read more comments on GitHub >

github_iconTop Results From Across the Web

JavaScript nested async function calls executed out of order
Some context: I'm trying to implement a functionality on a website that opens a panel on the left side, then inserts a form...
Read more >
Question on the order of actions, especially async actions. #602
Now I understand it. Basically, the orders of actions are determined by the time when a program dispatches (async) actions, not by the...
Read more >
Redux Fundamentals, Part 6: Async Logic and Data Fetching
The official Redux Fundamentals tutorial: learn how to use async logic with Redux.
Read more >
Async actions in bare Redux with Thunk or custom middleware
Learn how to manage asynchronous actions in React apps with Redux Toolkit, or a bare Redux implementation with custom middleware.
Read more >
async function - JavaScript - MDN Web Docs - Mozilla
The async function declaration declares an async function where the await keyword is permitted within the function body. The async and await ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found