2017-10-12 3 views
0

Je reçois vraiment un mal de tête en essayant d'utiliser la fonctionnalité async/wait lors de l'utilisation pour les boucles. J'utilise la version de Node.js: v8.6.0Avoir des problèmes Async/Await Promise - Javascript/Nodejs

En résumé, j'essaie de récupérer plusieurs lignes d'une base de données, puis de les placer toutes dans un tableau et de renvoyer ce tableau.

Je l'ai fait avec succès en utilisant des rappels, mais je n'arrive pas à comprendre comment le faire avec async/await.

Mon code actuel en utilisant callbacks qui fonctionne

function main(db) { 
    gatherDates(db, function(dates) { 
     console.log(dates); //successful 
    }); 
} 

function gatherDates(db, callback) { 
    const dates = []; 
    let today = getToday(); 

    dates.push(today); 

    let dateQuery = "SELECT date FROM event_dates"; 

    db.query(dateQuery, (err, newDates) => { 
     for(let row of newDates) { 
      dates.push(row.date); 
     } 
     callback(dates);    
    }); 
} 

Le code qui ne réussit pas essayer d'utiliser async/Attendent

async function main(db) { 
    let dates = await gatherDates(db); 
    console.log(dates); //undefined or not all of the data 
} 

function gatherDates(db) { 
    const dates = []; 
    let today = getToday(); 

    dates.push(today); 

    let dateQuery = "SELECT date FROM event_dates"; 

    db.query(dateQuery, (err, newDates) => { 
     for(let row of newDates) { 
      dates.push(row.date); 
     } 
     return Promise.resolve(dates); 
    }); 
} 

Je googled essayer de trouver une solution, je essayé d'utiliser plusieurs promesses, puis en appelant return Promise.all(promises); à la fin, mais cela n'a pas fonctionné. J'ai essayé return new Promise((resolve, reject)=>resolve(dates))};. J'ai regardé Promise et async/wait des tutoriels et des exemples qui fonctionnent habituellement pour moi mais quand il s'agit de faire défiler des données, c'est là que j'ai un problème. Je sais qu'il y a quelque chose de fondamental qui me manque et toute aide est appréciée. Je vous remercie!

Répondre

3

Le problème est que vous essayez de return la promesse de l'intérieur du rappel db.query, which can't work (et même lorsque vous avez essayé d'utiliser le constructeur de promesse, vous l'avez fait à l'intérieur de là, avec le même effet que Promise.resolve()). Le proper way to promisify doit utiliser new Promise à l'extérieur, de sorte que vous pouvez return partir de votre fonction externe, et mettre uniquement le resolve à l'intérieur du rappel asynchrone.

function query(sql) { 
    return new Promise((resolve, reject) { 
     db.query(sql, (err, res) => { 
      if (err) reject(err); 
      else resolve(res); 
     }); 
    }); 
} 

async function gatherDates(db) { 
    const dates = [getToday()]; 
    const newDates = await query("SELECT date FROM event_dates"); 
    for (let row of newDates) { 
     dates.push(row.date); 
    } 
    return dates; 
} 
+0

fonctionnait très bien! et maintenant je comprends mieux les promesses. Merci – nd510

0

Vous n'êtes pas correctement un objet retournerez Promise de votre fonction asynchrone, voici la solution:

function gatherDates(db) { 
    const dates = []; 
    let today = getToday(); 
    dates.push(today); 
    let dateQuery = "SELECT date FROM event_dates"; 

    return new Promise((resolve) => { 
     db.query(dateQuery, (err, newDates) => { 
      for(let row of newDates) { 
       dates.push(row.date); 
      } 
      resolve(dates); 
     }); 
    }); 
} 
+0

Vous devez également gérer les erreurs et les exceptions. – Bergi

+0

Vous devriez absolument faire cela, mais ce n'est pas ce qu'il demande, je préfère répondre avec le comportement exact requis. –

+0

Je ne vois pas où dans sa question le PO exige d'utiliser de mauvaises pratiques. – Bergi