XState:在没有中间状态的情况下链接多个 Promise

Posted

技术标签:

【中文标题】XState:在没有中间状态的情况下链接多个 Promise【英文标题】:XState: chaining multiple promises without intermediary states 【发布时间】:2020-01-12 16:33:59 【问题描述】:

我读过Invoking Multiple Services 部分,它说一个可以调用多个承诺,但在我自己的测试中,它们看起来被调用而不等待前一个完成

// ...
invoke: [
   id: 'service1', src: 'someService' ,
   id: 'service2', src: 'someService' ,
   id: 'logService', src: 'logService' 
],
// ...

Here 也是创建中间状态的解决方法

states: 
    first: 
      invoke: 
        src: 'one',
        onDone: 
          target: 'second',
        
      
    ,
    second: 
      invoke: 
        src: 'two',
        onDone: 
          target: 'success',
        
      
    ,
    success: 
      type: 'final'
    

有没有办法像Promise.each 这样使用调用进行链接,使调用([])可能串行运行?

我只能看到两个选项:

    中间状态 调用一个本身进行链接的承诺。

【问题讨论】:

是的,这两个似乎是您的选择。他们怎么了?当然,您甚至可以编写一个简单的函数,自动从一组服务中生成中间状态。 好吧,invoke SingleOrArray 界面看起来非常漂亮并且放在一起,似乎是一种很好的链接方式,并且非常清楚正在发生的事情。但它不是,因为是并行的,似乎没有办法告诉其他人,我试图找到的是类似 redux-saga 效果的东西,put 或call例如,但在 xstate 上下文中,调用不同的服务,并且能够随着应用程序的增长将它们组合起来,而无需创建中间函数。 那么promise链和内部机器的问题是你不能调用外部机器中定义的服务?在这种情况下,您可能应该在库的 repo 上发布功能请求。 【参考方案1】:

所有有状态的行为都需要在状态机中显式。如果您希望 Promise 顺序运行,那就是有状态的 - 您在下一个 Promise 开始之前检查每个 Promise 的状态。因此,您需要多个状态,就像您发布的解决方案一样。

但是,您可以创建一个辅助函数来满足您的需求:

async function sequence(...promiseCreators) 
  for (const promiseCreator of promiseCreators) 
    await promiseCreator();
  

  return;


// ...
invoke: 
  src: () => sequence(createPromise1, createPromise2, createAsyncLogger)

// ...

但这提出了进一步的问题:

如果发生错误怎么办? (加try/catch) 中断/取消怎么办?你是怎么处理的? 如何汇总从 Promise 中解析的数据? 如何处理依赖关系解析;即,承诺 A 依赖于来自承诺 B 的数据?

这些可以很容易地为您的用例回答,但有许多可能的用例需要考虑。这就是为什么最好明确承诺的顺序(使用中间状态)而不是让库 (XState) 对您的用例做出假设。

【讨论】:

所有这些点都可以通过串行invoke 选项来解决,因为invoke 处理所有这些分支。 很长一段时间后,我回到了这个问题,并同意在 XState 之外使用组合来获得更好的 ad-hoc 效果会更好。我想我当时是想看看 XState 是否有一个单子接口来组合状态/机器。 @CodingEdgar 这个想法的单子接口是什么样的?

以上是关于XState:在没有中间状态的情况下链接多个 Promise的主要内容,如果未能解决你的问题,请参考以下文章

有没有办法在 useEffect 的反应组件中设置 xstate 机器的状态?

如何在反应中保持 Xstate 状态机中的状态?

有没有办法使用从 Firebase 返回的承诺来初始化 Xstate 状态机?

在 xstate 中生成子机器

前端状态机系列:SCXML与XState对应关系

是否可以在不使用当前状态的条件语句的情况下使用状态机?