2017-03-05 2 views
0

Aus dem folgenden Code i, das Versprechen zu lösen versuchen nur nach den Spielen seiner Daten aus der api Schleife gefüllt Objekt hat, wenn der Sinn macht, aber es hält leer Anzeige:Beheben Sie das Versprechen erst, nachdem die Variable ausgefüllt wurde?

{ 
    info: summoner, 
    matchIds: {        << used for loop below 
     0: matchIds['matches'][0].matchId, 
     1: matchIds['matches'][1].matchId, 
     2: matchIds['matches'][2].matchId, 
     3: matchIds['matches'][3].matchId, 
     4: matchIds['matches'][4].matchId, 
     5: matchIds['matches'][5].matchId, 
     6: matchIds['matches'][6].matchId, 
     7: matchIds['matches'][7].matchId, 
     8: matchIds['matches'][8].matchId, 
     9: matchIds['matches'][9].matchId 
    } 
} 

var getMatches = function(summoner) { 
    var promise = new Promise(function(resolve, reject){ 
     var opt = {}; 
     var games = {};       << object needs to be filled 
     for (var val in Object.keys(summoner['matchIds'])) { 
      var match = summoner['matchIds'][val]; 
      opt.id = match; 
      api.getMatchById(opt, function(err, game) { 
       games[x] = game; 
      }) 
     } 
     console.log(games); 
     resolve({games}); 
    }); 
    return promise; 
}; 

Antwort

1

Ihr Code wird unter der Annahme, dass api.getMatchById() synchron , aber es ist wahrscheinlich nicht und damit die for Schleife abgeschlossen, bevor einer Ihrer api.getMatchById() Anrufe abgeschlossen, damit Spiele immer leer ist, wenn Sie auflösen. Sie müssen im Auge behalten, wenn alle api.getMatchById() Anrufe erledigt sind und nur auflösen, wenn das passiert.

Der beste Weg, dies zu kodieren wäre Promisify api.getMatchById() und dann Promise.all() zu verfolgen, wenn sie alle fertig sind. Wenn Sie wurden nicht tun werden, dann könnten Sie einen manuellen Zähler erstellen:

var getMatches = function(summoner) { 
    return new Promise(function(resolve, reject){ 
     var cntr = 0; 
     var opt = {}; 
     var games = {}; 
     var keys = Object.keys(summoner['matchIds']); 
     keys.forEach(function(key) { 
      var match = summoner['matchIds'][key]; 
      opt.id = match; 
      api.getMatchById(opt, function(err, game) { 
       // need some error handling here 
       games[x] = game; 
       ++cntr; 
       // when all api calls are done, resolve 
       if (cntr === keys.length) { 
        resolve({games}); 
       } 
      }) 
     }); 
    }); 
}; 

bitte auch immer nicht für/in, um die Elemente eines Arrays iterieren, wie es zu Problemen anfällig sein kann . In ES6 können Sie for/of verwenden. Ich habe .forEach() hier verwendet.

+0

@Elevant - Hat dies Ihre Frage beantwortet? – jfriend00

0

Hallo mögliche Lösung, wenn Gebrauch, nicht reine Versprechungen aber bluebird Bibliothek

const Promise = require('bluebird'); 
const promise = new Promise(function (resolve, reject) { 
    const propsPromise = {}; 
    Object.keys(summoner['matchIds']).forEach(val => { 
    const match = summoner['matchIds'][val]; 
    propsPromise[match] = new Promise((resolve, reject) => { 
     api.getMatchById(opt, (err, game) => { 
      if (err) { 
       return reject(err); 
      } 
      resolve(game); 
     }); 
    });}); 
    return Promise.props(propsPromise); 
}); 

Sie heraus Versprechen so schnell gelöst werden, wenn das Objekt mit Inhalt gelöst werden.

Link zur Dokumentation - Promise.props

+1

Sie haben Ihre 'return Promise.props (propsPromise) verlegt;' –

+0

@JaromandaX thnx, behoben. – Selvatico

Verwandte Themen