流星客户端异步模式 / 如何为订阅列表和回调实现 waitOn

meteor client async pattern / how to implement a waitOn for a list of subscriptions w callbacks

本文关键字:列表 回调 waitOn 实现 异步 客户端 模式 流星      更新时间:2023-09-26

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

由于这是 meteor 中的异步调用客户端,因此有哪些技术可以做到这一点?

如果我想有一个订阅列表,例如:

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

然后在应用程序的其余部分全部.ready() = true后开始

这样做的好方法是什么?

我不太明白 wait(( 方法是如何在这里的 IR 源代码中实现的

对于 aysnc.js 类型的情况来说,这似乎是一个理想的情况,我想调用一个方法列表并在它们的回调完成后继续,但诉诸节点样式模式对于 meteor 来说似乎有点笨拙。我查看了wrapAsync和meteorhacks异步实用程序,但这似乎主要用于服务器方法和包装NPM包。

如果我能对 ready(( 值列表求和,然后创建一个跟踪器,如果/当该总和发生变化时会触发...... ? 但也不太确定该怎么做。

由于每个订阅在完成后都会触发回调,我想我可以使用计数器来跟踪何时触发回调并保留一个计数器来检查数组的 == 长度,但这似乎又有点不优雅。

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

  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 如何选择其计算依赖项Tracker.autorun如何挑选它的计算?

我不确定你的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())
}