admin管理员组

文章数量:1420205

I've read the Invoking Multiple Services section, which says that one could invoke multiple promises, but in my own tests they look to be invoked without waiting for the previous to finish

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

Here is an answer as well with the workaround of creating intermediary states

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

Is there a way to do chaining like Promise.each, with invokes, making the invoke([]) run serially maybe ?

I can only see two options:

  1. Intermediate states
  2. Call one promise that does the chaining in itself.

I've read the Invoking Multiple Services section, which says that one could invoke multiple promises, but in my own tests they look to be invoked without waiting for the previous to finish

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

Here is an answer as well with the workaround of creating intermediary states

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

Is there a way to do chaining like Promise.each, with invokes, making the invoke([]) run serially maybe ?

I can only see two options:

  1. Intermediate states
  2. Call one promise that does the chaining in itself.
Share Improve this question edited Sep 11, 2019 at 0:47 Coding Edgar asked Sep 10, 2019 at 22:25 Coding EdgarCoding Edgar 1,4751 gold badge10 silver badges25 bronze badges 3
  • Yes, these two seem to be your options. What's wrong with them? Surely you could even write a simple function that produces intermediate states from an array of services automatically. – Bergi Commented Sep 10, 2019 at 23:32
  • Well the invoke SingleOrArray interface looked very nice and put together, seems like a nice way to chain and be very clear of what's happening. but its not, because is parallel and seems that there's no way to tell otherwise, what i'm trying find is something like redux-saga effects, put or callfor example, but in xstate context, invoking different services, and being able to bine them as the app grows without creating intermediary functions. – Coding Edgar Commented Sep 11, 2019 at 0:44
  • 1 So the problem with both promise chaining and with an internal machine is that you cannot invoke services defined in the outer machine? In that case, you probably should post a feature request on the library's repo. – Bergi Commented Sep 11, 2019 at 22:15
Add a ment  | 

1 Answer 1

Reset to default 9

All stateful behavior needs to be explicit in the state machine. If you want promises to run sequentially, that is stateful - you are checking the state of each promise before the next promise starts. Therefore, you need multiple states, just like the solution you posted.

However, you can create a helper function that does what you want:

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

  return;
}

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

But this poses further questions:

  • What if an error occurs? (add try/catch)
  • What about interruption/cancellation? How do you handle that?
  • How do you aggregate data resolved from the promises?
  • How do you handle dependency resolution; i.e., promise A depends on data from promise B?

These can be easily answered for your use-case but there are many possible use-cases to consider. That is why it's best to be explicit about the sequence of promises (using intermediary states) rather than let the library (XState) make assumptions about your use-cases.

本文标签: javascriptXState chaining multiple promises without intermediary statesStack Overflow