2015-10-30 16 views
11

Chcę utworzyć skrypt ładowania wstępnego, który wykonuje wiele funkcji asynchronicznych, aby pobrać zawartość zewnętrzną. Jestem dość blisko tutaj, ale nie do końca zrozumiałem, jak odroczyć wywołanie this.next() w mojej funkcji onBeforeAction. W poniższym kodzie widzę, że używam pętli i setTimeout, ale w jakiś sposób tracę kontekst mojego routera i this.next() jest niezdefiniowany. Wierzę, że dzieje się tak, ponieważ moja funkcja preloadProject dobiega końca, a Router ostrzega mnie, że zapomniałem wywołać this.next(); przed zakończeniem mojej funkcji waitToRender.Jak czekać na połączenia http w onBeforeAction Iron Routera?

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); 
     } 
    } 
} 

i mój ruter

Router.before(
    IR_BeforeHooks.preloadProject, 
    { 
     only:['editor', 'viewer', 'embedder'] 
    } 
); 

powodu skomplikowanych wymogów w moim projekcie muszę wykonać te zadania przed renderowania. Jak mogę zmusić Iron Routera do czekania na moje połączenia http bez blokowania przeglądarki?

Odpowiedz

1

Znalazłem rozwiązanie. Problem, jak podejrzewałem, polegał na tym, że Iron Router zerwał się, gdy moja podstawowa funkcja przechwytująca zakończyła działanie synchronizacji. Aby to naprawić, ustawiam własną kopię tego pliku. Niedawno, kiedy rozpoczynam swoją pracę, i wywołuję kopię tej funkcji po zakończeniu pracy asynchronicznej.

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(); 
     } 
    } 
    } 
} 
+0

Próbuję rozwiązać powiązany problem. Uprzejmie mi pomóc z tym [link] (https://stackoverflow.com/questions/46072958/where-do-i-place-my-meteor-callpromise-code-so-it-works-with-my-waiton- hook) Z góry dziękuję. – SirBT

0

Umieść router.next() poza blokiem else, nawet jeśli nie renderujesz niczego, co musisz wywołać 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(); 
+0

Doceniam odpowiedzi, problem jest to, że nie chcę, aby uczynić postęp jest aż 100. Jeśli kładę router.next() gdzie można polecić to będę skończyć renderingu na koniec pierwsza iteracja waitToRender i wywoływanie routera.następnie w kółko, dopóki moje połączenia http nie zostaną wykonane. – danSiebes