2016-08-01 4 views
0

Ich bin mir nicht sicher, wie ich mit conventions/bluebird meinen gewünschten Kontrollfluss adäquat erreichen kann.Was ist eine sinnvolle Möglichkeit, meinen Kontrollfluss zu strukturieren (Versprechen und Schleifen)?

Im Wesentlichen habe ich eine Datenbank mit X 'Aufgaben' gespeichert und jeder muss nacheinander geladen und ausgeführt werden. Ich möchte nicht mehr als eine Aufgabe gleichzeitig ausführen, und der gesamte Code muss unbegrenzt weiter ausgeführt werden.

Ich habe dies mit dem folgenden Code bisher erreicht:

export default function syncLoop() { 
    getNextTaskRunner().then((taskRunner) => { 
    if (taskRunner) { 
     taskRunner.startTask() 
     .then(syncLoop) 
     .catch((error) => { 
     throw new Error(error); 
     }); 
    } else { 
     syncLoop(); 
    } 
    }); 
} 

getNextTaskRunner() einfach Lasten und löse mit der nächsten Aufgabe aus der Datenbank (basierend auf Zeitstempel, berechnet). Oder es löst mit Null auf (keine Aufgabe verfügbar).

taskRunner.startTask() wird mit Null aufgelöst, wenn die vollständige Aufgabe abgeschlossen ist.

Ich wurde darauf hingewiesen, dass die Art und Weise, wie es strukturiert ist (rekursive/w Versprechen) zu Stack-Problemen führen könnte, nachdem es seit einiger Zeit ausgeführt wurde.

Was ich gedacht habe über das Tun ist es wie etwas zu restrukturieren:

let running = false; 
    setInterval(() => { 
    if (!running) { 
     running = true; 
     getNextTaskRunner().then((taskRunner) => { 
     if (taskRunner) { 
      taskRunner.startTask() 
      .then(() => { 
      running = false; 
      }) 
      .catch((error) => { 
      log.error(error); 
      }); 
     } else { 
      running = false; 
     } 
     }); 
    } 
    }, 5000); 

Oder noch eine andere Möglichkeit, in irgendeiner Form Ereignis Emittern mit?

task.on('complete', nextTask());

Gedanken und Ratschläge sehr geschätzt werden!

Antwort

1

Welche Stapelprobleme? Die Art und Weise, wie Sie Ihren Code geschrieben haben, ist vollkommen in Ordnung, solange getNextTaskRunner wirklich async ist (d. H., Es gibt die Kontrolle zu einem bestimmten Zeitpunkt an die Hauptschleife zurück, beispielsweise wenn es asynchron ist). In diesem Fall gibt es keine Rekursion in Ihrem Code. Wer auch immer dir das gesagt hat, der hat sich geirrt.

Obwohl Sie vielleicht eine setTimeout irgendwo hinzufügen möchten, so dass Sie Ihre Datenbank nicht mit Anfragen fluten. Außerdem wird es Ihnen helfen, wenn getNextTaskRunner nicht mehr synchron sein (aufgrund beispielsweise im Speicher-Caching):

export default function syncLoop() { 
    setTimeout(() => { 
    getNextTaskRunner().then((taskRunner) => { 
     if (taskRunner) { 
     taskRunner.startTask() 
      .then(syncLoop) 
      .catch((error) => { 
      throw new Error(error); 
      }); 
     } else { 
     syncLoop(); 
     } 
    }); 
    }, 2000); 
} 
+0

getNextTaskRunner definitiv async ist. Vielen Dank für das Feedback, sehr zu schätzen! – kurt343

Verwandte Themen