6

Rxjs TENET 问题解析

 3 years ago
source link: https://zhuanlan.zhihu.com/p/345917231
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

原文链接:

豆皮范儿:Rxjs TENET 问题解析 zhuanlan.zhihu.com

豆皮粉儿们,大家好,又见面了。

nQ7jim7.gif!mobile

众所周知,RxJS是非常流行的前端响应式异步编程框架,其丰富的操作符为异步编程带来了无限可能,但是数据平台的“阳羡”同学却遇到了观察值反向流动的问题,下面这篇文章讲述了问题的起因与解决过程。

本文作者:阳羡

引言

rxjs 一直是解决复杂异步问题的最优解,它能够把值像魔法一样在 Observable 间流动,但是最近我遇到了一个问题,发现值竟然能够反向流动,就像 TENET 中一样,非常不合常理。

问题代码

为了定位问题,我写了一个最小复现 demo,以下代码订阅了一个 Subject 并打印当前的值,问题是,打印的结果是什么?

https:// codesandbox.io/s/lucid- almeida-ti97w?file=/src/index.js

mAFvqiv.jpg!mobile

打印的结果是:

是这样的吗?

然而实际结果却是:

天啊,怎么可能,难道我穿越到 信条TENET 去了?为什么输出会反着来?

深入分析

为了深入探究这个问题,我们一起来写一个最小 Subject

qINf6bm.jpg!mobile

在实现过程中需要 注意一点

rxjs是复杂异步解决方案,但是本质上是同步的

同时在问题代码中,第一个 subscribe 加上 sub1 开头的 log,第二个 subscribe 加上 sub2 开头的 log

结果如下

sub1 1
sub1 2
sub1 3
sub2 3
sub2 2
sub2 1

再简化下,最终就是一个简单的 递归模型

IFbiYrr.jpg!mobile

再画出堆栈图

QbeQriQ.jpg!mobile

这样就很简洁明了了

解决办法

回到最初的问题,如果我们想让 App 中的值顺序输出,可以有哪些解决办法呢?

核心思路就是使用微任务,建立一个新的 task 从而不使用当前堆栈

方法一:

使用 setTimeout

niABzmV.jpg!mobile

方法二:

使用 delayoperator

beiyEnq.jpg!mobile

或者其他的类似方案

总结

遇见问题不要慌张,把复杂问题给最小化,最后发现就是一个简单问题,而解决最小简单问题的方案通常就是最终解决复杂问题的方案。

The End


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK