XState:等待调用函数的响应

Posted

技术标签:

【中文标题】XState:等待调用函数的响应【英文标题】:XState: Wait for response of invoked function 【发布时间】:2019-10-20 15:58:21 【问题描述】:

我计划在我的应用程序后端使用 XState 来管理状态。调用 api 时,将在成功更改状态时调用函数。函数调用的结果必须作为 api 的响应返回。

// Returns a Promise, e.g.:
// 
//   id: 42,
//   name: 'David',
//   friends: [2, 3, 5, 7, 9] // friend IDs
// 
function getUserInfo(context) 
return fetch('/api/users/#context.userId').then(response =>
 response.json()
);


// Returns a Promise
function getUserFriends(context) 
const  friends  = context.user;

return Promise.all(
 friends.map(friendId =>
  fetch('/api/users/#context.userId/').then(response => response.json())
  )
 );


const friendsMachine = Machine(
 id: 'friends',
 context:  userId: 42, user: undefined, friends: undefined ,
 initial: 'gettingUser',
 states: 
  gettingUser: 
   invoke: 
    src: getUserInfo,
    onDone: 
      target: 'gettingFriends',
      actions: assign(
        user: (context, event) => event.data
      )
    
   
  ,
  gettingFriends: 
   invoke: 
    src: getUserFriends,
    onDone: 
      target: 'success',
      actions: assign(
        friends: (context, event) => event.data
      )
    
   
  ,
 success: 
  type: 'final'
 

);


interpret(friendsMachine).start()

我希望将 getUserFriends 的输出作为我的 api 的响应发送。如何等待转换和所有调用完成?

【问题讨论】:

【参考方案1】:

您可以使用onDone (read the docs on invoking promises ?)

这是一个示例 Express 应用程序,它按顺序等待 2 个 Promise 完成,然后发送该数据:

function eventuallyGet(value) 
  return new Promise(res => 
    setTimeout(() => 
      res(value);
    , 1000)
  )


const getUserMachine = Machine(
  initial: 'fetchingName',
  context: 
    user: undefined
  ,
  states: 
    fetchingName: 
      invoke: 
        src: () => eventuallyGet('David'),
        onDone: 
          target: 'fetchingDetails',
          actions: assign(
            user: (ctx, e) => (
              ...ctx.user,
              name: e.data
            )
          )
        
      
    ,
    fetchingDetails: 
      invoke: 
        src: () => eventuallyGet( location: 'Florida' ),
        onDone: 
          target: 'success',
          actions: assign(
            user: (ctx, e) => (
              ...ctx.user,
              ...e.data
            )
          )
        
      
    ,
    success: 
      type: 'final',
      data: 
        user: ctx => ctx.user
      
    
  
);

app.get('/user', function(request, response) 
  interpret(getUserMachine)
    .onDone(e => 
      response.json(e.data);
    )
    .start();
);

您可以在此处查看代码:https://glitch.com/~pleasant-relish

【讨论】:

以上是关于XState:等待调用函数的响应的主要内容,如果未能解决你的问题,请参考以下文章

如何使用事件发射器调用返回值的函数,并在继续之前等待响应?

AWS lambda 实例在 xstate 调用承诺时关闭

性能优化之函数防抖动

如何让 Lambda 函数等待异步操作完成?

等待函数完成,直到回调到来

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