首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我如何强迫一个可观察的人完成?

我如何强迫一个可观察的人完成?
EN

Stack Overflow用户
提问于 2020-03-28 23:31:16
回答 1查看 146关注 0票数 0

有点小众的问题,但我知道问题是什么,所以希望这里的人能帮助我。这是一个可观察的/RXFire问题,而不是xstate问题。

我有一台可以观察到的机器:

代码语言:javascript
复制
export const tribeMachine = Machine(
  {
    id: "council",
    initial: "init",
    context: {},
    states: {
      init: {
        invoke: {
          id: "gettribes",
          src: () =>
            collectionData(database.collection("tribes")).pipe(
              concatAll(),
              map(x => ({ type: "STORE", x }))
            ),
          onDone: "loaded"
        },
        on: {
          STORE: {
            actions: "storetribes"
          },
          CANCEL: "loaded"
        }
      },
      loaded: {
        entry: () => console.log("loaded")
      },
      error: {
        entry: () => console.log("error")
      }
    }
  },
  {
    actions: {
      storetribes: (context, event) => console.log("hello")
    }
  }
);

它的工作方式应该是,机器在加载时调用可观察到的负载,然后,当obs发出其值和调用完成()后,调用invoke.onDone并将机器转换到“加载”状态。

当我使用用一个完整()调用创建的可观察到的正常值时,或者当我向我的.pipe()的末尾添加end (#)时,转换就能工作了。

但出于某种原因,从collectionData()到RXFire的可观察到的信号并不能发出‘完全’信号.机器就停在那里。

我尝试在末尾添加一个空(),并将-ing()连接到可观察到的位置,以便向管道的末尾添加一个完整的信号.但是后来我发现空()被废弃了,而且它似乎没有用。

我的头撞在墙上有一段时间了。任何帮助都是非常感谢的。

编辑:

解决方案:

我误解了collectionData()的目的。它是一个倾听者,所以它不应该完成。我在圆孔里放了个正方形的钉子。解决方案是重构xstate机器,因此我根本不需要调用onDone。

尽管如此,还是谢谢你的回答。

EDIT2:让它开始工作。

采取(1)可以在concatAll()之前调用。我以为如果你先叫它,它就会结束流,但它没有,管道中的其他操作符仍然适用。因此,我需要(1)获取单个数组,使用concatAll()将数组扁平为单个对象流,然后将数据映射到触发存储操作的新对象。然后,存储操作将数据设置为机器的上下文。

代码语言:javascript
复制
export const tribeMachine = Machine({
    id: 'council',
    initial: 'init',
    context: {
        tribes: {},
        markers: []
    },
    states: {
        init: {
            invoke: {
                id: 'gettribes',
                src: () => collectionData(database.collection('tribes')).pipe(
                    take(1),
                    concatAll(),
                    map(value => ({ type: 'TRIBESTORE', value })),
                ),
                onDone: 'loaded'
            },
            on: {
                TRIBESTORE: {
                    actions: ['storetribes', 'logtribes']
                },
                CANCEL: 'loaded'
            }
        },
        loaded: {
        },
        error: {
        }
    }
},
    {
        actions: {
            storetribes: assign((context, event) => {
                return {
                    tribes: {
                        ...context.tribes,
                        [event.value.id]: event.value
                     },
                     markers: [
                         ...context.markers,
                         {
                             lat: event.value.lat,
                             lng: event.value.lng,
                             title: event.value.tribeName
                         }
                        ]
                     }
            })
        }
    }
)

谢谢大家的帮助!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-03-29 06:34:23

随着时间的推移,可观测值可以返回多个值,因此由collectionData()来决定何时完成(即导致调用完整())。

但是,如果您只想从可观察到的值中获取1个值,则可以尝试:

代码语言:javascript
复制
  collectionData(database.collection("tribes")).pipe(
              take(1),
              concatAll(),
              map(x => ({ type: "STORE", x }))
            ),

这将导致可观察的完成,一旦您从collectionData()获得一个值。

注意:这可能不是最好的解决方案,因为它取决于您使用的可观察流是如何工作的。我只是强调,您可以使用take(1)只获取1个值并完成可观察的源。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60908323

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档