2 Stimmen

Nodejs async: mehrere abhängige HTTP-API-Aufrufe

Ich arbeite an einem Projekt, das das Senden mehrerer HTTP GET-Anforderungen an verschiedene APIs involviert, wobei jede Informationen vom letzten benötigt. Ich versuche, das Verschachteln von Rückruf- und Zählerhölle zu vermeiden und habe versucht, es mit dem async-Modul zum Laufen zu bringen.

Das ist, was ich tun muss: Ich habe ein Array von 1..n Kursidentifikatoren (['2014/summer/iat/100/d100', '2014/spring/bisc/372/d100']). Für jeden Kurs im Array muss ich sein Kursprogramm über einen HTTP GET abrufen.

Das resultierende Programm sieht ungefähr so aus:

{
  "info": {
    "nodePath": "2014/spring/bisc/372/d100",
    "number": "372",
    "section": "D100",
    "title": "Special Topics in Biology",
    "term": "Spring 2014",
    "description": "Selected topics in areas not currently offered...",
    "name": "BISC 372 D100",
    "dept": "BISC",
 },
 "instructor": [
    {
      "lastName": "Smith",
      "commonName": "Frank",
      "phone": "1 555 555-1234",
      "email": "franksmith@school.edu",
      "name": "Frank Smith",
      "roleCode": "PI"
    },
    {
      "lastName": "Doe",
      "commonName": "John",
      "phone": "1 555 555-9876",
      "email": "johndoe@school.edu",
      "name": "John Doe",
      "roleCode": "PI"
    }
  ]
}

(eine Menge nicht relevanter Felder weggelassen)

Jedes Kursprogramm-Objekt kann eine instructor-Eigenschaft enthalten, die ein Array von 0..n Dozentenobjekten für den Kurs ist. Für jedes Mitglied des instructor-Arrays muss ich dann eine weitere API aufrufen, um zusätzliche Daten zu erhalten. Wenn dieser Aufruf zurückkehrt, muss ich ihn in das richtige Dozentenobjekt einfügen.

Zum Schluss, wenn alles erledigt ist, werden die Daten an eine Vorlage übergeben, die express rendern und an den Client zurückgeben soll.

Ich habe versucht, dies mit async zum Laufen zu bringen und hatte mit async.waterfall Erfolg, als ich ein Proof-of-Concept nur mit dem Abrufen eines der Dozentenprofile gemacht habe (z.B. nicht über das Array iterieren, sondern nur instructor[0] bekommen). Die Dokumentation des async-Moduls ist umfassend, aber ziemlich dicht und ich habe Schwierigkeiten zu bestimmen, was ich tatsächlich tun muss. Ich hatte eine Frankenstein-Kombination verschiedener verschachtelter async-Aufrufe, die immer noch nicht funktionierten.

Es ist mir egal, wie ich die Aufgabe erledige - Flusssteuerung, Versprechungen, magischer Feenstaub, was auch immer. Jegliche Hinweise sind sehr willkommen.

3voto

dpogue Punkte 553

Mit Q für Versprechen können Sie wahrscheinlich etwas Ähnliches wie dies tun:

return Q
.all(course_ids.map(function(course) {
    return HTTP.GET(course); // Angenommen, dies gibt ein Versprechen zurück
}))
.then(function(course_data) {
    var instructors = [];

    course_data.forEach(function(course) {
        var p = Q
            .all(course.instructor.map(function(instructor) {
                return HTTP.GET(instructor.id);
            }))
            .then(function(instructors) {
                course.instructors_data = instructors;

                return course;
            });

        promises.push(p);
    });

    return Q.all(promises);
});

Wird mit einem Array gelöst, das die Kurse enthält, von denen jeder ein Array von Dozentendaten in seinem instructors_data Wert enthält.

1voto

mscdex Punkte 100829

Sie könnten async.each() verwenden, um die API-Anfragen parallel auszuführen (vorausgesetzt, auf der Serverseite gibt es keine gleichzeitigen API-Anfragebeschränkungen, verwenden Sie in diesem Fall stattdessen async.eachLimit()):

async.each(instructors, function(instructor, callback) {

  // Rufen Sie hier die API auf, speichern Sie das Ergebnis im `instructor`,
  // und rufen Sie `callback` auf, wenn Sie fertig sind

}, function(err){
  if (err)
    console.log('Beim Verarbeiten der Ausbilder ist ein Fehler aufgetreten');
  else
    console.log('Alle Ausbilder wurden erfolgreich verarbeitet');
});

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X