出于各种原因我正在编写一个不使用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?
答案 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())
}