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

Cod*_*gar 2 javascript typescript reactjs xstate

我已经阅读了调用多个服务部分,它说一个人可以调用多个承诺,但在我自己的测试中,它们看起来不需要等待前一个完成就被调用

// ...
invoke: [
  { id: 'service1', src: 'someService' },
  { id: 'service2', src: 'someService' },
  { id: 'logService', src: 'logService' }
],
// ...
Run Code Online (Sandbox Code Playgroud)

是一个答案以及创建中间状态的解决方法

states: {
    first: {
      invoke: {
        src: 'one',
        onDone: {
          target: 'second',
        }
      }
    },
    second: {
      invoke: {
        src: 'two',
        onDone: {
          target: 'success',
        }
      }
    },
    success: {
      type: 'final'
    }
}
Run Code Online (Sandbox Code Playgroud)

有没有办法Promise.each用调用进行链接,使 invoke([]) 串行运行?

我只能看到两个选项:

  1. 中间状态
  2. 调用一个自身进行链接的 promise。

Dav*_*hid 6

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

但是,您可以创建一个辅助函数来执行您想要的操作:

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

  return;
}

// ...
invoke: {
  src: () => sequence(createPromise1, createPromise2, createAsyncLogger)
}
// ...
Run Code Online (Sandbox Code Playgroud)

但这带来了进一步的问题:

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

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