Looping with Promises

Je suis dans un scénario où je dois obtenir des données du serveur en partie dans l'ordre, et j'aimerais le faire avec l'aide de Promises. C'est ce que j'ai essayé jusqu'à présent:

function getDataFromServer() { return new Promise(function(resolve, reject) { var result = []; (function fetchData(nextPageToken) { server.getData(nextPageToken).then(function(response) { result.push(response.data); if (response.nextPageToken) { fetchData(response.nextPageToken); } else { resolve(result); } }); })(null); }); } getDataFromServer().then(function(result) { console.log(result); }); 

La première tentative est réussie, mais les appels suivants sur server.getData() ne s'exécutent pas. Je présume qu'il s'agit de ce que le premier then() n'est pas rempli. Comment puis-je atténuer ce problème?

Nimrand répond à votre question ( catch manquante), mais voici votre code sans l' éditeur promesse antipattern :

 function getDataFromServer() { var result = []; function fetchData(nextPageToken) { return server.getData(nextPageToken).then(function(response) { result.push(response.data); if (response.nextPageToken) { return fetchData(response.nextPageToken); } else { return result; } }); } return fetchData(null); } getDataFromServer().then(function(result) { console.log(result); }) .catch(function(e) { console.error(e); }); 

Comme vous pouvez le voir, la récursivité fonctionne très bien avec des promesses.

 var console = { log: function(msg) { div.innerHTML += "<p>"+ msg +"</p>"; }}; var responses = [ { data: 1001, nextPageToken: 1 }, { data: 1002, nextPageToken: 2 }, { data: 1003, nextPageToken: 3 }, { data: 1004, nextPageToken: 4 }, { data: 1005, nextPageToken: 0 }, ]; var server = { getData: function(token) { return new Promise(function(resolve) { resolve(responses[token]); }); } }; function getDataFromServer() { var result = []; function fetchData(nextPageToken) { return server.getData(nextPageToken).then(function(response) { result.push(response.data); if (response.nextPageToken) { return fetchData(response.nextPageToken); } else { return result; } }); } return fetchData(0); } getDataFromServer().then(function(result) { console.log(result); }) .catch(function(e) { console.log(e); }); 
 <div id="div"></div> 

Parce que votre déclaration alors ne passe pas une fonction pour gérer les cas d'erreur, les requêtes au serveur pour les données peuvent échouer silencieusement, auquel cas la promesse retournée par getDataFromServer ne sera jamais terminée.

Pour résoudre ce problème, passez une deuxième fonction en tant qu'argument puis, comme ci-dessous:

 function getDataFromServer() { return new Promise(function(resolve, reject) { var result = []; (function fetchData(nextPageToken) { server.getData(nextPageToken).then(function(response) { result.push(response.data); if (response.nextPageToken) { fetchData(response.nextPageToken); } else { resolve(result); } }).catch(function(error) { //Note: Calling console.log here just to make it easy to confirm this //was the problem. You may wish to remove later. console.log("Error occurred while retrieving data from server: " + error); reject(error); }); })(null); }); }