3

I am trying to create an array of Promises which would print a message to the console when fulfilled. However, it seems to only print once even though there are 10 promise objects within the array.

I have tried the solution in ES6 Promises/calling a function after multiple promises are fulfilled (can't use Promises.all) but it still does not work.

function fillArrayWithPromise(promise, numTimes) {
  let promiseArr = Array(numTimes).fill(promise);
  console.log(promiseArr.join("-"));
  return promiseArr
}

var sendStuffB = new Promise(
  function(resolve, reject) {
    try {
      console.log("submitted one req");
    } catch (error) {
      console.log("Error: " + error);
    }
  }
)

let testA = fillArrayWithPromise(sendStuffB, 10);

Promise.all(
  testA.map(promise => Promise.resolve(promise).catch(err => console.log(error)))
).then(function() {
  console.log("End");
});

I expected the console to print 10 times of "One object sent" but it is only printed to the console once and continues to run indefinitely afterwards.

Here is the error log: Running Test Script... One object sent submitted one req [object Promise]-[object Promise]-[object Promise]-[object Promise]-[object Promise]-[object Promise]-[object Promise]-[object Promise]-[object Promise]-[object Promise]

Ayush Gupta
  • 8,716
  • 8
  • 59
  • 92
Tofu Lee
  • 95
  • 1
  • 9
  • _"but it is only printed to the console once"_ - Because there's only one actual `Promise` in your script. `promise` in `fillArrayWithPromise` is a reference to `sendStuffB`, hence you end with an array of `numTimes` copies of this reference - but no copies of the referenced `Promise` – Andreas Jun 20 '19 at 08:03
  • NB: It is quite useless do copy the same promise object in an array. – trincot Jun 20 '19 at 08:08
  • 1
    Two errors here: you don't resolve the promise, and you have the same promise (which will execute only just once) 10 times. – Iván Pérez Jun 20 '19 at 08:10

3 Answers3

3

Because sendStuffB is only one promise, so it is resolved only once. All the other items in your array are reference to the same resolved promise.

Instead of this, in fillArrayWithPromise function, pass a function which returns a promise, and call that function seperately for each array item.

Also, always remember to resolve or reject the promise in the promise constructor function as needed.

function fillArrayWithPromise(promiseFn, numTimes) {
  let promiseArr = Array(numTimes).fill(promiseFn).map(fn => fn()); //see this
  return promiseArr
}

var sendStuffB = () => new Promise(  // converted to function
  function(resolve, reject) {
    try {
      console.log("submitted one req");
      resolve(); // remember to resolve
    } catch (error) {
      console.log("Error: " + error);
      reject(error); // reject
    }
  }
)

let testA = fillArrayWithPromise(sendStuffB, 10);

Promise.all(
  testA.map(promise => Promise.resolve(promise).catch(err => console.log(error)))
).then(function() {
  console.log("End");
});
Ayush Gupta
  • 8,716
  • 8
  • 59
  • 92
0

You are not calling the resolve function in the promises, so they never complete. Try doing this:

var sendStuffB = new Promise(
  function(resolve, reject) {
    try {
      console.log("submitted one req");
      resolve();
    } catch (error) {
      console.log("Error: " + error);
      reject(error);
    }
  }
)
Tom Holmes
  • 1,196
  • 8
  • 11
  • @Andreas - when the function was called when the promise was created. Note that the function **never completes**, not *never gets called* – slebetman Jun 20 '19 at 08:10
  • @Tom not resolving prevents `End` from being printed. It should not affect `submitted one req` – Ayush Gupta Jun 20 '19 at 08:13
  • @AyushGupta you're right there is only one promise that is being waited on 10 times (as opposed to creating 10 separate promises like in your answer, which is likely what was desired) – Tom Holmes Jun 20 '19 at 08:18
  • 2
    @Andreas `Promise.resolve` creates a new promise that immediately resolves to the value you pass in, however when that value is a promise, it waits for that promise to resolve and returns its resolution value. This doesn't force the passed in promise to resolve, but waits for it. – Tom Holmes Jun 20 '19 at 08:20
0

This is a basic example of the Promise.all functionality.

It might help you.

const delayArray = [1000,1500,2000];

const promises = delayArray.map((item) => {
  return new Promise((resolve,reject) => {
    setTimeout(()=>{
      console.log('I was resolved in' + item + 'ms');
      resolve('Resolved' + item + 'ms');
    },item);
  });
});

Promise.all(promises)
.then((values) => console.log(values));
cbdeveloper
  • 27,898
  • 37
  • 155
  • 336