J'essaie de décomposer les promesses, car je souhaite éventuellement renvoyer les résultats d'une requête SQL dans la promesse myPromise, de sorte que je termine avec une liste des résultats de nombreuses requêtes SQL.

var myList = [];

for (let i = 1; i <= 20; i++) {
  var myPromise = new Promise(function(resolve, reject) {
    myList.push(myPromise);
    resolve("ITEM " + i);
  })
}

Promise.all(myList).then(function(values) {
  console.log(values);
});

console.log("End");

Production:

[ undefined,
  'ITEM 1',
  'ITEM 2',
  'ITEM 3',
  'ITEM 4',
  'ITEM 5',
  'ITEM 6',
  'ITEM 7',
  'ITEM 8',
  'ITEM 9',
  'ITEM 10',
  'ITEM 11',
  'ITEM 12',
  'ITEM 13',
  'ITEM 14',
  'ITEM 15',
  'ITEM 16',
  'ITEM 17',
  'ITEM 18',
  'ITEM 19' ]

Comment je comprends comment cela fonctionne : Ma boucle ajoute immédiatement une nouvelle promesse à myList, puis lorsqu'elle est résolue, la promesse est remplacée par la valeur de chaîne transmise à resolve.

Cela fonctionne bien mais je me retrouve avec 1 valeur indéfinie au début. J'ai 20 éléments au total qui sont attendus, mais un n'est pas défini. Pourquoi est-ce?

0
Birdman 18 mars 2019 à 02:27

2 réponses

Meilleure réponse

Le myPromise que vous poussez vers myList est créé après l'exécution du constructeur Promise. Ainsi, à la première itération, myPromise est undefined (et aux itérations suivantes, le dernier myPromise est poussé vers le tableau).

Construisez la promesse, puis immédiatement poussez vers le tableau dans la même itération à la place :

var myList = [];

for (let i = 1; i <= 20; i++) {
  var myPromise = new Promise(function(resolve, reject) {
    resolve("ITEM " + i);
  });
  myList.push(myPromise);
}
Promise.all(myList).then(function(values) {
  console.log(values);
});

console.log("End");

Cela pourrait être plus clair si vous soulevez manuellement le myPromise (afin que vous voyiez le code plus près de la façon dont l'interpréteur l'exécute):

var myPromise;
var myList = [];
for (let i = 1; i <= 20; i++) {
  myPromise = new Promise(function(resolve, reject) {
    resolve("ITEM " + i);
  });
  myList.push(myPromise);
}
Promise.all(myList).then(function(values) {
  console.log(values);
});

console.log("End");
3
CertainPerformance 17 mars 2019 à 23:32

La première fois, vous poussez myPromise vers myList alors qu'il n'est toujours pas défini.

Vous pouvez résoudre ce problème en évitant complètement la variable myPromise.

var myList = [];

for (let i = 1; i <= 20; i++) {
    myList.push(new Promise(function(resolve, reject) {
        resolve("ITEM " + i);
    }))
}

Ou pousser à myList par la suite.

for (let i = 1; i <= 20; i++) {
    var myPromise = new Promise(function(resolve, reject) {
        resolve("ITEM " + i);
    })
    myList.push(myPromise);
}
3
Michael 17 mars 2019 à 23:32