2016-04-14 13 views
0

Ich versuche mehrere asynchrone Anforderungen in JS zusammen zu ketten. Im Grunde möchte ich die Künstlerinformationen von der LastFM-API abrufen und dann diese Informationen nach ihren besten Titeln durchsuchen.Mehrere Versprechen Anforderungen verkettet in Javascript

Bis jetzt kann ich die Künstlerinfo erfolgreich erhalten, es zurückgeben lassen, und es druckt die Info im folgenden Schritt aus. Sobald ich jedoch versuche, meine zweite Anfrage für die Top-Tracks zu machen, wird der Body nie gedruckt und es geht sofort weiter zum nächsten Schritt.

Ich habe viele verschiedene Kombinationen dieses Codes mit verschiedenen Arten von Anfragen und dergleichen ausprobiert, aber ich habe kein Glück bekommen. Ich möchte nur erfolgreich 1 anfordern, wenn es erfolgreich ist, dann folge es von anderen in einer ordnungsgemäßen Reihenfolge.

 var artistInfo = { 
      method: 'GET', 
      url: 'http://localhost:3000/users/db/artistInfo/' + artistName 
     }; 


     var topTracks = { method: 'GET', 
      url: 'http://localhost:3000/users/db/topTracks/' + artistName 
     }; 

     /* Dependencies */ 
     var Promise = require('bluebird'); 
     var reqP = Promise.promisifyAll(require('request-promise')); 

     reqP(artistInfo) 
      .then(function(info) { 

       console.log("got here 1"); 
       return info; 
      }) 
      .then(function(artist) { 

       console.log(artist); 

       reqP(topTracks) 
        .then(function(body) { 

         console.log(body); 

         console.log("got here 2"); 
         return body; 
       }); 

       return 'test'; 
      }) 
      .then(function(content) { 

       console.log(content); 

       return 'test2'; 
      }) 
      .catch(function(err) { 
       throw err; 
      }); 
+0

Warum Sie diese beiden Anfragen Sequenzierung sind zu vermeiden? Man scheint nicht von dem anderen abhängig zu sein. Sie könnten sie parallel starten und 'Promise.all()' verwenden, um zu sehen, wann beide fertig sind. – jfriend00

Antwort

1

diese beiden Anfragen sequenzieren und die äußere .then() warten beide haben, müssen Sie sie die interne Versprechen (die eine in der .then() Handler), um Kette zurückzukehren. Wenn Sie sie nicht zurückgeben, dann ist nichts an das Elternversprechen gebunden und deshalb wartet das Elternversprechen nicht auf das Kinderversprechen. Siehe die Linie, wo ich return-return reqP(topTracks) hinzugefügt:

var artistInfo = { 
     method: 'GET', 
     url: 'http://localhost:3000/users/db/artistInfo/' + artistName 
    }; 


    var topTracks = { method: 'GET', 
     url: 'http://localhost:3000/users/db/topTracks/' + artistName 
    }; 

    /* Dependencies */ 
    var Promise = require('bluebird'); 
    var reqP = Promise.promisifyAll(require('request-promise')); 

    reqP(artistInfo) 
     .then(function(info) { 

      console.log("got here 1"); 
      return info; 
     }) 
     .then(function(artist) { 

      console.log(artist); 

      // *** add return here *** 
      return reqP(topTracks) 
       .then(function(body) { 

        console.log(body); 

        console.log("got here 2"); 
        return body; 
      }); 
     }) 
     .then(function(content) { 

      console.log(content); 

      return 'test2'; 
     }) 
     .catch(function(err) { 
      throw err; 
     }); 

FYI, sieht es nicht wie Ihre zwei Anforderungen hängen von einander so könnten Sie auch tun, um sie parallel:

var artistInfo = { 
     method: 'GET', 
     url: 'http://localhost:3000/users/db/artistInfo/' + artistName 
    }; 

    var topTracks = { method: 'GET', 
     url: 'http://localhost:3000/users/db/topTracks/' + artistName 
    }; 

    /* Dependencies */ 
    var Promise = require('bluebird'); 
    var reqP = Promise.promisifyAll(require('request-promise')); 

    Promise.all([reqP(artistInfo), reqP(topTracks)]).then(function(results){ 
     // results[0] is artist 
     // results[1] is tracks 
    }, function(err){ 
     // error here 
    }); 
+0

Ich habe das mit einer Rückkehr dort versucht. Habe es einfach nochmal gemacht und wie davor noch nicht einmal Logging "Here 2". Es sagt mir, dass er die Anforderung trifft, da ich in meiner Anfrage ein Protokoll haben sagen „Top Track-Erfolg“, aber es meldet sich nie den Körper und ich kann wirklich nicht verstehen, warum (ich habe auch von der Rück Prüfbit los). – rmw

+0

@mw - Dann haben Sie irgendwo ein Fehler oder ein logisches Problem. Das Versprechen zurückzugeben ist, wie Sie es verketten. So wird es gemacht. Wenn Sie 'console.log (artist)' sehen, aber 'console.log (" get here 2 ") nicht sehen,' 'reqP (toptracks)' muss ablehnen. – jfriend00

+0

Nein. Ich sehe innerhalb von 'http: // localhost: 3000/users/db/topTracks /' ein Protokoll, in dem eine Erfolgsmeldung ausgegeben wird. Es wird jedoch niemals 'console.log (body)' oder irgendetwas darunter angezeigt. – rmw

0

Erstens, ich weiß nicht, warum Sie eine Versprechen-basierte Bibliothek versprechen. Es gibt ein paar Möglichkeiten, dies zu tun, aber ich werde Ihnen geben, was ich denke, ist der sauberste Weg, aber es erfordert Bluebird (die Sie in Ihrem Beispiel sowieso verwenden, sollte also kein Problem sein)

Es sieht nicht so aus wie Ihre zweite Anfrage an Ihrem ersten abhängt, Sie Promise.props()

/* Dependencies */ 
 
var Promise = require('bluebird'); 
 
var request = require('request-promise'); 
 

 
var artistInfo = request({ 
 
    method: 'GET', 
 
    url: 'http://localhost:3000/users/db/artistInfo/' + artistName 
 
}); 
 

 

 
var topTracks = request({ 
 
    method: 'GET', 
 
    url: 'http://localhost:3000/users/db/topTracks/' + artistName 
 
}); 
 

 

 

 
Promise.props({ 
 
    artistInfo: artistInfo, 
 
    topTracks: topTracks 
 
}).then(function(result) { 
 
    console.log(JSON.stringify(result.artistInfo,null,2)); 
 
    console.log(JSON.stringify(result.topTracks,null,2)); 
 
}) 
 
.catch(function(err) { 
 
    console.error(err); 
 
});

So verwenden können, was hier vor sich geht? Promise.props können Sie ein Objekt übergeben, dessen Eigenschaften Versprechen sind. Diese Versprechungen werden dann parallel ausgeführt und das Versprechen wird nicht gelöst, bis beide gelöst sind (oder es wird fallengelassen, wenn eines der beiden fehlschlägt).

Wie für die Verkettung Versprechen, müssen Sie sicherstellen, dass Sie ein Versprechen zurückgeben. Dies ist, was können Sie die hässliche Verschachtelung

/* Dependencies */ 
 
var Promise = require('bluebird'); 
 
var request = require('request-promise'); 
 

 
request({ 
 
    method: 'GET', 
 
    url: 'http://localhost:3000/users/db/artistInfo/' + artistName 
 
}) 
 
.then(function(artistInfo) { 
 
    console.log(artistInfo); 
 
    
 
    return request({ 
 
    method: 'GET', 
 
    url: 'http://localhost:3000/users/db/topTracks/' + artistName 
 
    }); 
 
}) 
 
.then(function(topTracks) { 
 
    console.log(topTracks); 
 
}) 
 
.catch(function(err) { 
 
    console.error(err); 
 
});

Verwandte Themen