2015-10-30 7 views
11

Ich möchte ein Preloading-Skript erstellen, das eine Reihe von asynchronen Funktionen zum Herunterladen externer Inhalte ausführt. Ich bin ziemlich nah hier, aber ich habe nicht wirklich herausgefunden, wie man diese.next() in meiner onBeforeAction-Funktion aufrufen. In dem Code unten sehen Sie, dass ich eine Schleife und setTimeout verwende, aber ich verliere irgendwie den Kontext meines Routers und this.next() ist undefiniert. Ich glaube, das liegt daran, dass meine preloadProject-Funktion zu Ende geht und der Router warnt, dass ich vergessen habe, dies zu nennen.next(); bevor meine waitToRender-Funktion beendet wird.Wie warten auf http Anrufe in Iron Routers onBeforeAction?

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

und meinem Router

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

Wegen komplizierten Anforderungen in meinem Projekt muss ich diese Aufgaben vor dem Rendern. Wie kann ich Iron Router auf meine http-Anrufe warten lassen, ohne den Browser zu blockieren?

Antwort

1

Ich habe eine Lösung gefunden. Das Problem, wie ich vermutete, war, dass der Iron Router sich selbst auf null stellte, als meine primäre Hook-Funktion ihre Synchronisierungsarbeit beendete. Um dies zu beheben, richte ich meine eigene Kopie dieser Datei ein, wenn ich mit meiner Arbeit beginne, und rufe meine Kopie der Funktion auf, wenn meine asynchrone Arbeit abgeschlossen ist.

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

Ich versuche ein ähnliches Problem zu lösen. Bitte helfen Sie mir mit diesem [link] (https://stackoverflow.com/questions/46072958/where-do-i-place-my-meteor-callpromise-code-so-it-works-with-my-waiton- Haken) Danke im Voraus. – SirBT

0

Setzen Sie router.next() außerhalb else Block, auch wenn Sie nichts rendern müssen Sie next aufrufen.

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

ich die Antwort zu schätzen weiß, ist das Problem, dass ich will nicht machen, bis Fortschritte bei 100. Wenn ich router.next put(), wo Sie empfehlen, dann werde ich mache am Ende des Ende erste Wiederholung von waitToRender und router.next immer wieder anzurufen, bis meine http-Aufrufe erledigt sind. – danSiebes

Verwandte Themen