【mobx学习笔记】异步操作方法

 
 

前言

mobx的action中调用异步函数的时候,会有一个“陷阱”。下面举例说明

假设有这样一个类

class Store {
    @observable test1 = 0
    @observable test2 = 0
	@computed get testCom() {
        return this.test1 + this.test2
    }
    constructor() {
        autorun(() => {
            console.log("autorun: ", this.testCom)
        })
}

以及一个异步操作。

function getDataFromServer() {
    return new Promise(reslove => {
        setTimeout(() => {
            console.log("请求完毕返回yangguang");
            reslove("yangguang")
        }, 1000);
    })
}

如果像下面这样去编写action并调用的话,autorun会执行几次呢?

class Store {
    @observable test1 = 0
    @observable test2 = 0
	@computed get testCom() {
        return this.test1 + this.test2
    }
    constructor() {
        autorun(() => {
            console.log("autorun: ", this.testCom)
        })
     @action.bound getDatas() {
        console.log("开始请求数据")
        this.test1 = 0
        const data = getDataFromServer().then((data) => {
            console.log(`拿到数据了:${data}`)
            this.test1 = 55
            this.test2 = 155
        })
        console.log("请求结束")
        this.test1 = 666
    }
}

答案是3次,结果如下图
在这里插入图片描述
原因在于,then()所包裹的回调函数并不属于getDatas方法的一部分,这个回调是由promise去调用的,而不是getDatas方法。换句话说,下图中红框圈出的部分是同步代码,而绿框圈出的部分是异步代码,两者属于不同的栈,@action只能作用于同步代码这部分,所以this.test1 = 0this.test1 = 666两个对test1的操作被合并了,而回调函数中对数据操作的语句this.test1 = 55;this.test2 = 155,并没有被@action覆盖到,于是就理所当然的触发了两次autorun(就像不使用action那样)
在这里插入图片描述
原因既然找到了,那解决起来就简单了。下面给出三种解决办法(写法),其实这三种也是大家一下子就能想到的。

action/runInAction

第一种:将设置state的语句抽离成单独的action。如下图
在这里插入图片描述

第二种:使用action方法
唯一的缺点是回调函数所有代码都放在action中了,如果仍然希望只将修改数据的部分放在action中,可以使用runInAction。
在这里插入图片描述
第三种:使用action的语法糖runInAction
在这里插入图片描述
这三种的打印结果完全相同,如下图:
打印结果如下:
在这里插入图片描述

async/await

但其实上面那三种方法都很啰嗦,使用es6的async/await会让代码清爽一些
在这里插入图片描述
大家觉得这样调用会输出什么呢?还和前三种方法一样吗?当然不一样,甚至会让人有些费解。请看下图
在这里插入图片描述
先说明一件事:await/async只是promise的语法糖,因此@action同样只能负责到await之前的代码,await之后的代码就不归@action管了。所以this.test1 = 100;this.test1 = 123被合并了,而后面的四次修改没有被合并,触发了四次autorun。知道了原因修改起来就简单了,修改后的代码如下:
在这里插入图片描述
控制台打印结果如下:
在这里插入图片描述

flow

当当当当~ 主角登场,前面说了那么多其实只是想让大家知道其他方法有多么的麻烦。来看看使用mobx提供的flow方法会让代码有多么简单和清爽,使用flow之后代码如下(别忘了在文件头引入flow方法):
在这里插入图片描述
输入如下:
在这里插入图片描述
看看,整个getDatasFlows方法没有使用任何action,无比的清爽干净!请看下图,相同颜色框框内的数据操作被合并了,至于原因刚刚也说过了。可以理解为yield之后的每一个框框都被一个runInAction方法包裹住了。
在这里插入图片描述
以上,谢谢阅读!

  • 6
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值