简体   繁体   中英

Promise.all doesn't work as intended

I have a few asynchronous calls I want to execute before my final call, and i have similar method to this stackoverflow answer .

Here is the code in Codepen

class Person {
  name: string;
  constructor(init){
    this.name = init;
  }
}
let people: Person[] = [];
let names:string[] = ['janes','james','jo','john','josh'];
names.forEach(n=>people.push(new Person(n)));
function printName(name:string) {
  let getSomething = new Promise(function(resolve, reject) {
    setTimeout(function() {
      resolve(name);  
    },1000)
  });
  getSomething.then(function(){
    console.log(name);
  });
}
/// main
let request = [];
console.log('start');
people.forEach(person => { 
  request.push(printName(person.name));
})
Promise.all(request).then(result=> {
  console.log(result);
  console.log("finsh");
})

What the above code produced:

"start"
[undefined, undefined, undefined, undefined, undefined]
"finsh"
"janes"
"james"
"jo"
"john"
"josh"

while what I am expecting:

"start"
"janes"
"james"
"jo"
"john"
"josh"
[undefined, undefined, undefined, undefined, undefined]
"finsh"

You're not returning the promises created in printName to the request array, so Promise.all is being called on an array of undefined s (and, as a result, resolves immediately). Chain and return the promises instead.

Often, when you use Promise.all , you want the resolved array to contain values and not undefined s - for that, also return name inside getSomething.then so that the Promise.all will resolve with an array of names:

function printName(name:string) {
  let getSomething = new Promise(function(resolve, reject) {
    setTimeout(function() {
      resolve(name);  
    },1000)
  });
  return getSomething.then(function(){
    console.log(name);
    return name; // add this line too
  });
}

Working snippet in ordinary Javascript:

 class Person { constructor(init){ this.name = init; } } let people = []; let names = ['janes','james','jo','john','josh']; names.forEach(n=>people.push(new Person(n))); function printName(name) { let getSomething = new Promise(function(resolve, reject) { setTimeout(function() { resolve(name); },1000) }); return getSomething.then(function(){ console.log(name); return name; }); } let request = []; console.log('start'); people.forEach(person => { request.push(printName(person.name)); }) Promise.all(request).then(result=> { console.log(result); console.log("finsh"); }) 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM