2016-09-15 3 views
0

Ich versuche ein Skript zu schreiben, das die GitHub API verwendet. Ich habe eine Funktion, die eine Liste von Benutzernamen akzeptiert. Für jeden Benutzernamen wird ein Aufruf an die API vorgenommen, um die markierten Repos der Nutzer zu erhalten. Für jeden User-Repo möchte ich den Namen des Repos und die Anzahl der Sterne notieren, schließlich möchte ich mit diesen Daten mehr arbeiten.Promise.all() verhält sich unerwartet, wo ist mein Unverständnis?

Ich versuche, dies mit nur nativen Versprechen zu implementieren und vermeiden Q, Bluebird usw. Hier ist, was ich habe, die nicht funktioniert.

function getNameAndStarInfo(repo){ 
    return new Promise(function(resolve, reject){ 
    //i'd like this to return an object but it has to be an iterable?? 
    resolve([{[repo.full_name] : repo.stargazers_count}]); 
    }); 
}; 

function getStarredRepos(usernames){ 
    var promises =[]; 
    for (var user in usernames){ 
    //build the header for API request 

    var name = usernames[user]; 
    var url = 'https://api.github.com/users/' + name + '/starred'; 
    var header = {url: url, headers: {'User-Agent': 'username', 'Authorization': 'token blahblabhlabh'}, json: true }; 

    //for the current user make a request and get their starred repos 
    request(header, function(err, res, usersStarredRepos){ 
     for (var repo in usersStarredRepos){ 
      promises.push(getNameAndStarInfo(usersStarredRepos[repo])); 

     }; 
    }); 
    }; 
    Promise.all(promises) 
     .then(function(promises){ 
     //dont need to log, would like to do stuff with this data later 
     console.log(promises); 
    }); 

}; 

Im Wesentlichen Ich erwarte ein all den {name: stargazers_count} um zu sehen, Daten, wenn ich das Array anmelden, nachdem in der .then() -Methode. Ein leeres Array wird jedoch jedes Mal ausgegeben. Kann mir jemand erklären, was ich hier vermisse?

+0

Sie versprechen. alles auf einem leeren Array. Etwas von einem Duplikat von: http://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call –

+0

"* es muss ein iterable sein ?? *" - warum denkst du das? – Bergi

Antwort

1

Sie sind drücken in promises nur wenn eine Anfrage bereits erledigt ist. Wenn also Promise.all ausgeführt wird, ist das Array immer noch leer, weil noch keiner von ihnen fertig ist.

mit dieser Art und Weise versuchen:

function getNameAndStarInfo(repo) { 
    return new Promise(function(resolve, reject) { 
     //i'd like this to return an object but it has to be an iterable?? 
     resolve([{ 
      [repo.full_name]: repo.stargazers_count 
     }]); 
    }); 
} 

function getUserStars(username) { 
    return new Promise(function(resolve, reject) { 
     var name = username.name; 
     var url = 'https://api.github.com/users/' + name + '/starred'; 
     var header = { url: url, headers: { 'User-Agent': 'username', 'Authorization': 'token blahblabhlabh' }, json: true }; 
     //for the current user make a request and get their starred repos 
     request(header, function(err, res, usersStarredRepos) { 
      var promises = []; 
      for (var repo in usersStarredRepos) { 
       promises.push(getNameAndStarInfo(usersStarredRepos[repo])); 
      }; 
      Promise.all(promises).then(resolve).catch(reject); 
     }); 
    }); 
} 

function getStarredRepos(usernames) { 
    var promises = []; 
    for (var user in usernames) { 
     promises.push(getUserStars(usernames[user])); 
    } 
    Promise.all(promises).then(console.log).catch(console.log); 
} 

Aber Promises Erstellung zu vermeiden manuell Anfragen zu bearbeiten, ich würde vorschlagen, Sie Anfrage-Versprechen zu verwenden: genannt

https://www.npmjs.com/package/request-promise

+0

Das ist die richtige Antwort! –

+0

Vermeiden Sie die ['Promise' Konstruktor Antipattern] (http://stackoverflow.com/q/23803743/1048572)! Sie sollten nur 'request' promi- vieren und darauf zugreifen. – Bergi

+0

@Bergi die Frage ist ausschließlich über Promise.all und nicht auf Promises Muster. Er fragte, warum das Promise.all nicht so funktionierte, wie er es erwartet hatte. Ich erzählte ihm die Ursache und schrieb dann einfach einen Code (nach seinen Mustern) als Beispiel. Über die Anzahl der befohlenen Anfragen sehe ich das nicht. Ich habe viele Anfragen ausgelöst, eine für jeden Benutzer. Der Code wurde nicht einmal benötigt. Er hat nur nach einer Erklärung gefragt. –