11

I was trying to follow along with the MDN promise.all example but it seems I cannot pass more arguments to the setTimeout callback.

var p1 = new Promise((resolve, reject) => { 
  setTimeout(resolve, 200, 1,2,3); 
});
var p2 = new Promise((resolve, reject) => { 
  setTimeout(resolve, 500, "two"); 
});

Promise.all([p1, p2]).then(value => { 
  console.log(value);
}, reason => {
  console.log(reason)
});

This prints [1, "two"], where I would expect [1, 2, 3, "two"]. Doing this with setTimeout without promise fulfillment works as expected

setTimeout(cb, 100, 1, 2, 3);
function cb(a, b, c){
  console.log(a, b, c);
}
//=>1 2 3

Why doesn't this work with the promise? How can it be made to work with the promise?

1252748
  • 12,116
  • 27
  • 89
  • 197

2 Answers2

12

The resolve function only takes a single argument. You can't change that as this is the spec.

Passing more than that doesn't make a difference, and your other values are ignored.

You can opt to pass an array to the resolve function, but you'll get an array on the then handler, not independent values like you wanted.

Amit
  • 41,690
  • 8
  • 66
  • 101
6

resolve() only accepts and processes one argument and a fulfilled promise only has one value. This is per the promise specification and is not something you can change.

If you want to pass multiple pieces of info, then you can wrap the multiple pieces of data into either an array or an object and use that one object as the resolved value and then change the receiving code to access it in the wrapped object:

var p1 = new Promise((resolve, reject) => { 
  // put multiple resolved values into an array
  setTimeout(resolve, 200, [1,2,3]), 200); 
});
var p2 = new Promise((resolve, reject) => { 
  setTimeout(resolve, 500, "two"); 
});

Promise.all([p1, p2]).then(value => { 
  console.log(value);   // [[1,2,3], "two"]
}, reason => {
  console.log(reason)
});

If you really want indpendent values inside the final .then() handler that don't have embedded arrays, then you can flatten the value array in the .then() handler before you process the results. There are many techniques here for flattening arrays: Merge/flatten an array of arrays in JavaScript?

Community
  • 1
  • 1
jfriend00
  • 580,699
  • 78
  • 809
  • 825
  • 1
    You can also pass destructuring assignments to the `then` handler, provided the number of `Promise`s is known: `.then(([first, second]) =>`. –  Sep 27 '16 at 18:00