Async is encapsulated based on [rx.js](https://github.com/reactivex/rxjs) in order to respond to asynchronous events in the application in same way, such as networks, messages, server pushes, etc., and Provides basic anti-shake, timeout, and cancellation features.

The sr71 module is introduced in every logic.js file:

```js
import { asyncSuit } from '@/utils'

const { SR71 } = asyncSuit
const sr71$ = new SR71()
```

> sr71 is the code name of the US military blackbird reconnaissance plane:

![image](https://user-images.githubusercontent.com/6184465/51725044-34d67380-209b-11e9-87a4-9edeec396958.png)

### Network event

You can call a network request in a function, query and mutate represent the query and mutate operations in GraphQL respectively.

```js
Sr71$.query(S.pagedPosts, args)
// or
Sr71$.mutate(S.updateProfile, args)
```

Correspondingly, in DataSolver, the data returned by the server is responded to (DataSover is automatically generated by the `make gen` generator):

```js
Const DataSolver = [
  {
    Match: asyncRes('updateProfile'),
    Action: () => {
      updateDone()
      cancelLoading()
    },
  },
]
```

### Asynchronous message

The container component can listen for asynchronous events that need to be responded during initialization, such as:

```js
Const sr71$ = new SR71({
  receive: [
    EVENT.DRAWER.OPEN,
    EVENT.DRAWER_CLOSE,
    EVENT.UPLOAD_IMG_START,
    EVENT.UPLOAD_IMG_FINISH,
  ],
})
```

Retrieve 4 messages on behalf of the container component, EVENT.DRAWER.OPEN, EVENT.DRAWER.CLOSE, EVENT.UPLOAD_IMG_START, EVENT.UPLOAD_IMG_FINISH

Corresponding DataSolver:

```js
{
    Match: asyncRes(EVENT.DRAWER.OPEN),
    Action: res => {
      Const payload = res[EVENT.DRAWER.OPEN]
      lockPage()

      Store.open(payload)
    },
  },
  {
    Match: asyncRes(EVENT.DRAWER.CLOSE),
    Action: () => closeDrawer(),
  },
  {
    Match: asyncRes(EVENT.UPLOAD_IMG_START),
    Action: () => store.mark({ imageUploading: true }),
  },
  {
    Match: asyncRes(EVENT.UPLOAD_IMG_FINISH),
    Action: () => {
      setTimeout(() => {
        store.mark({ imageUploading: false })
      }, 500)
    },
  },
```

### Push event

Similar to TODO

### Error handling

The logical unification of error handling is handled by ErrSolver in a unified manner in response to GraphQL parsing errors, request errors, timeout errors, network errors, and so on. `errRescue` is a global error prompt, display component ([details](https://github.com/coderplanets/coderplanets_web/issues/340)), and the internal state of some components after the error, such as loading, etc. Handled here.

```js
Const ErrSolver = [
  {
    Match: asyncErr(ERR.GRAPHQL),
    Action: () => cancelLoading(),
  },
  {
    Match: asyncErr(ERR.TIMEOUT),
    Action: ({ details }) => {
      cancelLoading()
      errRescue({ type: ERR.TIMEOUT, details, path: 'AccountEditor' })
    },
  },
  {
    Match: asyncErr(ERR.NETWORK),
    Action: () => {
      cancelLoading()
      errRescue({ type: ERR.NETWORK, path: 'AccountEditor' })
    },
  },
]
```

![image](https://user-images.githubusercontent.com/6184465/51435747-e5b6ca00-1cb9-11e9-8da7-19e027675dd5.png)
