zoukankan      html  css  js  c++  java
  • [Web] mobx 异步操作

    转载自:https://www.jianshu.com/p/66dd328726d7

    异步action

    action只能影响正在运行的函数,而无法影响当前函数调用的异步操作 。action 包装/装饰器只会对当前运行的函数作出反应,而不会对当前运行函数所调用的函数(不包含在当前函数之内)作出反应
    也就是说promise的then或async语句,并且在回调函数中某些状态改变了,这些回调函数也应该包装在action中。
    (1)第一种方案,使用action关键字来包装promises的回调函数。
    // 第一种写法
    class Store {
    
    @observable githubProjects = []
    @observable state = "pending" // "pending" / "done" / "error"
    
    @action
    fetchProjects() {
        this.githubProjects = []
        this.state = "pending"
        fetchGithubProjectsSomehow().then(
            // 内联创建的动作
            action("fetchSuccess", projects => {
                const filteredProjects = somePreprocessing(projects)
                this.githubProjects = filteredProjects
                this.state = "done"
            }),
            // 内联创建的动作
            action("fetchError", error => {
                this.state = "error"
            })
        )
     }
    }

    // 第二种写法

     class Store {
         @observable githubProjects = []
         @observable state = "pending" // "pending" / "done" / "error"
    
         @action
         fetchProjects() {
             this.githubProjects = []
             this.state = "pending"
             fetchGithubProjectsSomehow().then(
                 projects => {
                     const filteredProjects = somePreprocessing(projects)
                     // 将修改放入一个异步动作中
                     runInAction(() => {
                         this.githubProjects = filteredProjects
                         this.state = "done"
                      })
                 },
                 error => {
                     runInAction(() => {
                         this.state = "error"
                     })
                 }
             )
         }
     }

    第二种方案,用async function来处理业务,那么我们可以使用runInAction这个API来解决之前的问题 。

    import {observable, action, useStrict, runInAction} from 'mobx';
    useStrict(true);
    
    class Store {
      @observable name = '';
      @action load = async () => {
        const data = await getData();
        // await之后,修改状态需要动作
        runInAction(() => {
          this.name = data.name;
        });
      }
    }
    1. flows
      然而,更好的方式是使用 flow 的内置概念。它们使用生成器。一开始可能看起来很不适应,但它的工作原理与 async / await 是一样的。只是使用 function * 来代替 async,使用 yield 代替 await 。 使用 flow 的优点是它在语法上基本与 async / await 是相同的 (只是关键字不同),并且不需要手动用 @action 来包装异步代码,这样代码更简洁。

    flow 只能作为函数使用,不能作为装饰器使用。 flow 可以很好的与 MobX 开发者工具集成,所以很容易追踪 async 函数的过程。

    mobx.configure({ enforceActions: true })
    
    class Store {
        @observable githubProjects = []
        @observable state = "pending"
    
        fetchProjects = flow(function * () { // <- 注意*号,这是生成器函数!
            this.githubProjects = []
            this.state = "pending"
            try {
                const projects = yield fetchGithubProjectsSomehow() // 用 yield 代替 await
                const filteredProjects = somePreprocessing(projects)
                // 异步代码块会被自动包装成动作并修改状态
                this.state = "done"
                this.githubProjects = filteredProjects
            } catch (error) {
                this.state = "error"
            }
        })
    }


  • 相关阅读:
    yii 引入文件
    CodeForces 621C Wet Shark and Flowers
    面试题题解
    POJ 2251 Dungeon Master
    HDU 5935 Car(模拟)
    HDU 5938 Four Operations(暴力枚举)
    CodeForces 722C Destroying Array(并查集)
    HDU 5547 Sudoku(dfs)
    HDU 5583 Kingdom of Black and White(模拟)
    HDU 5512 Pagodas(等差数列)
  • 原文地址:https://www.cnblogs.com/0616--ataozhijia/p/11727935.html
Copyright © 2011-2022 走看看