如何在 Iron Router 的 onBeforeAction 中等待 http 调用?
How to wait on http calls in Iron Router’s onBeforeAction?
我想创建一个预加载脚本来执行许多异步功能来下载外部内容。我在这里非常接近,但我还没有完全弄清楚如何在我的 onBeforeAction 函数中推迟调用 this.next() 。在下面的代码中,您可以看到我使用了一个循环和 setTimeout,但我以某种方式丢失了我的路由器的上下文并且 this.next() 未定义。我相信这是因为我的 preloadProject 函数结束了,路由器警告我忘记调用 this.next();在我的 waitToRender 函数完成之前。
if (Meteor.isClient) {
IR_BeforeHooks = {
preloadProject: function() {
var itemsProcessed = 0;
_.each(items.items, function(e) {
HTTP.get(e.S3URL, {
headers: {
'Accept': '*/*'
},
responseType: 'arraybuffer' //requires aldeed:http
}, function(error, result) {
if (error) {
Session.set('error', {
'title': 'Could not download',
'message': error
});
}
if (result) {
itemsProcessed = itemsProcessed + 1;
}
}) //http get
}) //each
function waitToRender(router) {
console.log('waiting...')
var progress = (itemsProcessed / items.items.length) * 100;
if (progress < 100) {
$('.progress-bar').css('width', Math.floor(progress) + '%');
setTimeout((function() {
waitToRender(router);
}), 50);
//console.log('timeout for a few ms here')
}
else {
console.log('all done, render');
router.next(); // I get this is not a function error here
}
}
waitToRender(this);
}
}
}
和我的路由器
Router.before(
IR_BeforeHooks.preloadProject,
{
only:['editor', 'viewer', 'embedder']
}
);
由于我项目中的复杂要求,我需要在渲染之前执行这些任务。如何让 Iron Router 在不阻塞浏览器的情况下等待我的 http 调用?
将 router.next()
放在 else
块之外,即使您没有渲染任何需要调用 next
.
的东西
if (progress < 100) {
$('.progress-bar').css('width', Math.floor(progress) + '%');
setTimeout((function() {
waitToRender(router);
}), 50);
//console.log('timeout for a few ms here')
}
else {
console.log('all done, render');
}
router.next();
我找到了解决办法。正如我所怀疑的那样,问题是当我的主要钩子函数完成同步工作时,Iron Router 正在将其自身清零。因此,为了解决这个问题,我在开始工作时设置了自己的 this.next 副本,并在异步工作完成时调用我的函数副本。
IR_BeforeHooks = {
preloadProject: function() {
var myNext = this.next;
...//http calls and etc
function waitToRender(router) {
console.log('waiting...')
var progress = (itemsProcessed / items.items.length) * 100;
if (progress < 100) {
...//use set timeout to recall waitToRender
}
else{
myNext();
}
}
}
}
我想创建一个预加载脚本来执行许多异步功能来下载外部内容。我在这里非常接近,但我还没有完全弄清楚如何在我的 onBeforeAction 函数中推迟调用 this.next() 。在下面的代码中,您可以看到我使用了一个循环和 setTimeout,但我以某种方式丢失了我的路由器的上下文并且 this.next() 未定义。我相信这是因为我的 preloadProject 函数结束了,路由器警告我忘记调用 this.next();在我的 waitToRender 函数完成之前。
if (Meteor.isClient) {
IR_BeforeHooks = {
preloadProject: function() {
var itemsProcessed = 0;
_.each(items.items, function(e) {
HTTP.get(e.S3URL, {
headers: {
'Accept': '*/*'
},
responseType: 'arraybuffer' //requires aldeed:http
}, function(error, result) {
if (error) {
Session.set('error', {
'title': 'Could not download',
'message': error
});
}
if (result) {
itemsProcessed = itemsProcessed + 1;
}
}) //http get
}) //each
function waitToRender(router) {
console.log('waiting...')
var progress = (itemsProcessed / items.items.length) * 100;
if (progress < 100) {
$('.progress-bar').css('width', Math.floor(progress) + '%');
setTimeout((function() {
waitToRender(router);
}), 50);
//console.log('timeout for a few ms here')
}
else {
console.log('all done, render');
router.next(); // I get this is not a function error here
}
}
waitToRender(this);
}
}
}
和我的路由器
Router.before(
IR_BeforeHooks.preloadProject,
{
only:['editor', 'viewer', 'embedder']
}
);
由于我项目中的复杂要求,我需要在渲染之前执行这些任务。如何让 Iron Router 在不阻塞浏览器的情况下等待我的 http 调用?
将 router.next()
放在 else
块之外,即使您没有渲染任何需要调用 next
.
if (progress < 100) {
$('.progress-bar').css('width', Math.floor(progress) + '%');
setTimeout((function() {
waitToRender(router);
}), 50);
//console.log('timeout for a few ms here')
}
else {
console.log('all done, render');
}
router.next();
我找到了解决办法。正如我所怀疑的那样,问题是当我的主要钩子函数完成同步工作时,Iron Router 正在将其自身清零。因此,为了解决这个问题,我在开始工作时设置了自己的 this.next 副本,并在异步工作完成时调用我的函数副本。
IR_BeforeHooks = {
preloadProject: function() {
var myNext = this.next;
...//http calls and etc
function waitToRender(router) {
console.log('waiting...')
var progress = (itemsProcessed / items.items.length) * 100;
if (progress < 100) {
...//use set timeout to recall waitToRender
}
else{
myNext();
}
}
}
}