
Are you serial, Promise.all? - jadengore
https://bramanti.me/are-you-serial-promise-all/
======
madeofpalk
When you actually look at the code, and how you're executing the functions, it
makes sense that Promise.all doesn't magically make your promises run in
serial.

    
    
        Promise.all([
          knex.schema.renameTable('tomatoes', 'potatoes'),
          knex.schema.table('potatoes', (table) => table.string('name'))
        ]);
    

Promise.all doesn't execute the functions - you're doing that yourself. The
argument you're passing to Promise.all is just an array of already kicked-off
promises. Consider it rewritten as:

    
    
        const promise1 = knex.schema.renameTable('tomatoes', 'potatoes’);
        const promise2 = knex.schema.table('potatoes', (table) => table.string('name’));
        Promise.all([promise1, promise2]);
    

Promise.all is just create a new Promise for you that is resolved when the
promises you pass in are all resolved.

In fact, looking at the 'solution' to this (Promise.series), it still suffers
from the same problem. See this demo of it still not working
[https://tonicdev.com/56da37cb0ba4470d00919c26/56da37cb0ba447...](https://tonicdev.com/56da37cb0ba4470d00919c26/56da37cb0ba4470d00919c27)

~~~
jadengore
Awesome find! I was not considering that a promise is executing as soon as it
is created, and this is why the implementation still results in parallel
execution.

I've gone back to the drawing board, and I've updated my post accordingly with
a better solution using reduce. I've also used your demo above as an example
and credited you in my article (please let me know if that is not OK, and I
will take it down).

Thanks again!

------
nostrademons
The canonical way to execute a collection of promises serially is through
Array.prototype.reduce:

    
    
      let finalResult = promises.reduce((current, next) => current.then(next), Promise.resolve());
    

(I've used ES6 syntax, but you can do this in ES5.1 as well. You can also
substitute Promise.prototype.then.call for the arrow function.)

The beauty of this one-liner is that it works with any promise-like object:
you don't need to use BlueBird, you don't even need to use a uniform promise
implementation, it'll work with anything that follows the Promises/A+ spec.

~~~
jadengore
This is cool! Thanks for sharing!

In my case, there is a bit less code, but I really do appreciate how your
implementation is not Bluebird-dependent.

------
flattersatz
I believe promise.each is not serial in the way you think it is. Promises do
handle only the resolution of certain events. So in your example both
statements are executed exactly at the time you set up your array of promises.
Promises.each then only ensures that their promise handlers are executed in
sequence.

So instead of promises you could create an array of arrow functions and with
promise.each execute one after the other.

~~~
jadengore
I've come up with a similar implementation, I will credit you for inspiring a
working solution in my article! Thank you very much!

