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


  • 相关阅读:
    linux C程序中获取shell脚本输出(如获取system命令输出)
    Vue实现网页在线拍照和上传 幸福n
    c# thread数线程的创建多线程(一)
    C#开启异步 线程的四种方式(二)
    web学习网站
    C#中的set和get方法
    C# 多线程之Task任务(三)
    Taro3 扫描不同二维码参数不同,但是热启动之后参数不变
    Taro 弹窗阻止小程序滑动穿透(亲测有效) tabbar数据缓存不更新 入口场景值不同
    《Webpack+Babel入门与实例详解》出版了
  • 原文地址:https://www.cnblogs.com/0616--ataozhijia/p/11727935.html
Copyright © 2011-2022 走看看