asyncAction

asyncAction takes a generator function and automatically wraps all parts of the process in actions. asyncAction can be used both as decorator or to wrap functions.

  • It is important that asyncAction should always be used with .a generator function (recognizable as function_or_name syntax).
  • Each yield statement should return a Promise. The generator function will continue as soon as the promise settles, with the settled value.
  • When the generator function finishes, you can return a normal value. The asyncAction wrapped function will always produce a promise delivering that value.

When using the MobX DevTools, an asyncAction will emit action events with names like:

  • "fetchUsers - runid: 6 - init"
  • "fetchUsers - runid: 6 - yield 0"
  • "fetchUsers - runid: 6 = yield 1"

The runId represents the generator instance. In other words, if fetchUsers is invoked multiple times concurrently, the events with the same runid belong together. The yield number indicates the progress of the generator. init indicates spawning (it won't do anything, but you can find the original arguments of the asyncAction here). yield 0...yield n indicates the code block taht is now being executed. yield 0 is before the first yield, yield 1 after the first one, etc. Note: Yield numbers are not determined lexically, but by the runtime flow.

asyncActions requires Promise and generators to be available on the target environment. Polyfill Promise if needed. Both TypeScript and Bable can compile generator functions down to ES5.

Parameters

  • arg1
  • arg2

Returns

  • Promise

Examples

import {asyncAction} from "mobx-utils"

let users = []

const fetchUsers = asyncAction("fetchUsers", function* (url) {
  const start = Date.now()
  const data = yield window.fetch(url)
  users = yield data.json()
  return start - Date.now()
})

fetchUsers("http://users.com").then(time => {
  console.dir("Got users", users, "in ", time, "ms")
})
import {asyncAction} from "mobx-utils"

mobx.useStrict(true) // don't allow state modifications outside actions

class Store {
    \@observable githubProjects = []
    \@state = "pending" // "pending" / "done" / "error"

    \@asyncAction
    *fetchProjects() { // <- note the star, this a generator function!
        this.githubProjects = []
        this.state = "pending"
        try {
            const projects = yield fetchGithubProjectsSomehow() // yield instead of await
            const filteredProjects = somePreprocessing(projects)
            // the asynchronous blocks will automatically be wrapped actions
            this.state = "done"
            this.githubProjects = filteredProjects
        } catch (error) {
            this.state = "error"
        }
    }
}

results matching ""

    No results matching ""