meteor客户端异步模式/如何实现一个waitOn用于订阅列表w回调

时间:2014-10-14 06:16:06

标签: javascript asynchronous meteor iron-router

出于各种原因我正在编写一个不使用IronRouter的应用程序,但必须实现一些类似的逻辑。一个是等待订阅列表准备就绪。

由于这是meteor中的异步调用客户端,有什么技巧可以做到这一点?

如果我想要一个潜艇列表,如:

  sublist = [
    PubSubMan.subscribe("Players"),
    PubSubMan.subscribe("Stuff")
  ]

然后从应用的其余部分开始.ready() = true

这样做的好方法是什么?

我不太明白在IR source code here

中如何实现wait()方法

这似乎是aysnc.js类型情况的理想情况,我想调用方法列表并在完成回调时继续,但是对于流星来说,采用节点样式模式似乎有些笨拙。我查看了wrapAsync和meteorhacks async utils,但这似乎主要用于服务器方法和包装NPM包。

如果我可以对ready()值的列表求和,然后创建一个Tracker deps,如果/当该总和发生变化时会触发......?但不太确定如何做到这一点。

由于每个订阅在完成时都会触发回调,我想我可以使用计数器来跟踪何时触发回调并保持计数器以检查==数组的长度,但这又看起来有点不合适。

编辑: 这不是一个理想的解决方案,但以下工作。但我仍然认为我错过了一种更优雅的方法。

  subList = [
    PubSubMan.subscribe("Players"),
    PubSubMan.subscribe("Stuff" )
  ]

  Tracker.autorun (c) =>
    subReady = _.filter subList, (item) ->
      return item.ready()
    allDone = (subList.length == subReady.length)
    console.log("subs status: #{subReady.length} / #{subList.length} = ready: #{allDone}")
    if allDone
      c.stop()
      startMainLoop()

与tracker.autorun如何选择其计算依赖关系的这个问题有关 how does Tracker.autorun pick out its computation?

1 个答案:

答案 0 :(得分:0)

我不确定你的startMainLoop是什么样的,但这是一种可能适合你的方法。创建一个新模板,只检查所有订阅是否准备就绪;如果它们是渲染真实的主模板,如果它们不是那么它渲染一个加载模板。

<template name="subscriptionsReadyCheck">
  {{#if allSubsAreReady}}
    {{> mainTemplate}}
  {{else}}
    {{> loadingTemplate}}
  {{/if}}
</template>
subList = [...]

Template.subscriptionsReadyCheck.helpers {
  allSubsAreReady: -> _.every(subList, (sub) -> sub.ready())
}

这假设订阅是在页面加载时创建的,并一直保持到页面关闭。如果您需要仅在呈现模板时创建并在模板被销毁时停止的订阅,您可以将它们存储在模板实例上:

Template.subscriptionsReadyCheck.created = ->
  @subList = [...]

Template.subscriptionReadyCheck.destroyed ->
  for sub in @subList
    sub.stop()

Template.subscriptionsReadyCheck.helpers {
  allSubsAreReady: -> _.every(Template.instance().subList, (sub) -> sub.ready())
}