XState:链接多个promise,无需中间状态

时间:2019-09-10 22:25:15

标签: javascript reactjs typescript xstate

我已经阅读了Invoking Multiple Services部分,该部分说一个可以调用多个promise,但是在我自己的测试中,它们看起来像是在被调用而无需等待前一个完成

// ...
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([])可以串行运行?

我只能看到两个选项:

  1. 中间状态
  2. 称一个自己做链接的诺言。

1 个答案:

答案 0 :(得分:3)

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

但是,您可以创建执行所需功能的辅助函数:

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

  return;
}

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

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

  • 如果发生错误怎么办? (添加try/catch
  • 中断/取消怎么办?您如何处理?
  • 您如何汇总从承诺中解决的数据?
  • 您如何处理依赖关系解析;即承诺A取决于承诺B的数据?

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