【问题标题】:Meteor how to wait on callback before dispatching Redux actionMeteor 如何在调度 Redux 操作之前等待回调
【发布时间】:2016-05-25 22:59:30
【问题描述】:

Meteor 使用回调,但 Redux 操作似乎没有“等待”它们。因此,如果使用 Redux 之类的内容并执行以下操作:

export function loginWithPassword(email, password) {
  return dispatch => {
    Meteor.loginWithPassword(email, password, error => {
      if (error) {
        return dispatch({type: ASYNC_ERROR, data: error.reason})
    });
  }
} 

...该操作将在 Meteor 调用之前完成并返回(因此如果需要,不会重新渲染 UI)。我已经搜索了几个小时试图找到处理这个问题的最佳方法,但无济于事。根据我所能找到的,似乎选项是 Meteor FuturesPromises,但我找不到任何表明哪个更好或为什么更好的东西。

我相信 Futures 只能是服务器端,并且没有 Promises 广泛使用,因此基于此,Promises 可能是更好的选择。我什至不确定 Futures 是否是一个选项,因为操作是客户端。但我也不确定 Meteor 是否能很好地与 Promises 配合使用,因为它具有一般的同步特性。

Promise 我相信可以是客户端或服务器。假设它们是客户端,将它们放在动作中还是在调度动作的 UI 代码中会更好 - 还是真的很重要?

是否有人对如何最好地处理此类事情有任何想法或见解?一个或另一个(或两者)的工作示例会很棒,因为经过几个小时的搜索,我肯定找不到一个。具体来说,很高兴看到一个简单的 Meteor 登录示例,其密码通过 Redux 分派,在 UI 登录表单中显示“未找到用户”或其他一些“异步”错误(第一次)。

上面的动作确实有效,但它在 Meteor 完成返回错误之前返回,因此错误不会在初始时间显示在 UI 中。

TIA!

附:有几个示例可以在警报窗口或 console.log 中显示错误 - 但这与在调度操作的 UI 中将其更新/显示为道具不同。没有与警报或 console.log 相关的道具重新渲染。整个想法是在用户当前使用的表单中显示错误(在此示例中为登录表单)

【问题讨论】:

  • 你能指出 Meteor 声称在这件事上同步的地方吗?我知道没有这样的说法。 Meteor 方法回调本质上是异步的,因此您需要以异步形式处理它,无论是 Redux 还是任何其他状态管理器。
  • 请参阅此处的 API 部分作为说明 Meteor API 是同步的示例...github.com/meteorhacks/meteor-async
  • 这仅与服务器有关。 Fibers 允许 Meteor 在服务器上使用带有异步 API 的同步语法,但它与客户端无关。顺便说一句,您链接到的存储库不是官方 Meteor 资源,尽管 Arunoda 是 Meteor 社区的杰出成员。
  • 好的,谢谢 - 但问题不在于 Meteor 同步还是异步......这是如何最好地“延迟”直到 Meteor 回调完成,然后再根据结果调度后续 Redux 操作.
  • 这与任何其他 Redux 异步流程有何不同?你可以有一个“待定”状态,当回调被调用时会改变。

标签: javascript meteor redux


【解决方案1】:

使用 redux-thunk,您可以编写如下所示的内容。我认为这里的技巧是一旦登录就知道用户对象的状态。这样做的一种方法是在Tracker.autorun 中使用store.dispatch

// whenever the reactive data changes, we will dispatch the appropriate action
Tracker.autorun(() => {
  if (Meteor.loggingIn()) {
    return store.dispatch({
      type: LOGGING_IN,
    });
  }

  const user = Meteor.user();

  store.dispatch({
    type: SET_USER,
    user,
  }
});

export const login = ({ email, password }) => (dispatch) => {
  Meteor.loginWithPassword(email, password, (error) => {
    if (error) {
      return dispatch({
        type: LOGIN_ERROR,
        error,
      });
    }

    return dispatch({
      type: LOGIN_SUCCESS,
    });
  });
};

你可以想象一个用户 reducer 的状态类似于 {user: {loggingIn: Boolean, authError: SomeErrorModel}}} 或类似的东西

您可以清除LOGGING_IN上的authError,然后将其添加到LOGIN_ERROR

对于基于此 reducer 的任何 UI 更改,只需将您的 react 组件与 react-reduxconnect() 连接即可

【讨论】:

  • 当您使用 Thunk 异步执行请求时,Meteor 提供的 Optimistic UI 会发生什么情况,不会导致延迟吗?另外,您将 Tracker.autorun() 放在哪里,在 Presentation 或 Container 中?
  • Optimistic UI 应该更改 Tracker 内部的 Meteor.user() 并在收到来自服务器的问题时恢复。
  • 关于 Tracker.autorun(),这更像是一个宏大的概念,但我喜欢将所有 Meteor 逻辑与组件分开。 Meteor 发生在 Tracker.autorun 或 action 中,通知 reducer,并在组件上使用 redux 的 connect()。通过这种设置,所有 Meteor 状态都保存在 redux 中,并且所有组件都知道是 redux 状态。否则,您最终会将 Meteor 和 redux 状态分开,现在您需要跟踪两个状态存储,这可能是一场噩梦
  • 我本来打算写一篇关于这个的大博文,但是这个家伙打败了我,我真的很认同他的组织:subvisual.co/blog/posts/79-a-bridge-between-redux-and-meteor
  • 通常流星中的分页发生在订阅级别。您可以设置会话或反应变量以传递给 Meteor.subscribe (或包装它的包)。使用 redux,您可以使用 action 和 reducer 管理这些 var。上面的博客显示了使用此设置处理订阅的一种方法
猜你喜欢
  • 2019-12-29
  • 2020-04-23
  • 1970-01-01
  • 1970-01-01
  • 2020-02-20
  • 2021-03-05
  • 1970-01-01
  • 2011-01-06
  • 2018-11-20
相关资源
最近更新 更多