• [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"
            }
        })
    }


  • 相关阅读:
    超贴心的,手把手教你写爬虫
    人生苦短我用Python,本文助你快速入门
    RocketMQ 安装
    RocketMQ 简介
    2020年工作上的最大收获——监控告警体系
    .NET Core开源任务调度平台ScheduleMaster上新了
    从源码角度分析ScheduleMaster的节点管理流程
    使用 K8s 进行作业调度实战分享
    图解 K8s 核心概念和术语
    深度剖析 Kafka Producer 的缓冲池机制【图解 + 源码分析】
  • 原文地址:https://www.cnblogs.com/0616--ataozhijia/p/11727935.html
Copyright © 2020-2023  润新知