7

I've been playing around with a few different ways of chaining a collection of functions and can't seem to find one I particularly like. The following is the last one I settled on but am still not keen on it.

Can someone suggest a cleaner and more concise pattern? I don't want to opt for Async.js or a library.

[
  this.connectDatabase.bind(this),
  this.connectServer.bind(this),
  this.listen.bind(this)
].reduce(
  (chain, fn) => {
    let p = new Promise(fn);
    chain.then(p);
    return p;
  },
  Promise.resolve()
);

Ps. any other tips are more than welcomed.

ddibiase
  • 1,412
  • 1
  • 20
  • 44

2 Answers2

12

Found this solution on stackoverflow on how you can chain promises dynamically:

iterable.reduce((p, fn) => p.then(fn), Promise.resolve())

The complete post is here: https://stackoverflow.com/a/30823708/4052701

Community
  • 1
  • 1
TiagoLr
  • 2,782
  • 22
  • 16
2

What about ES7 async/await? Strange/old bind(this) in your code, but kept to not confuse with your example.

async function x() {
    try {
        await this.connectDatabase.bind(this);
        await this.connectServer.bind(this);
        await this.listen.bind(this);
    } catch(e) {
        throw e;
    }
}

or more generic

async function () {
    for (let item of yourArray) {
        try {
            await item.bind(this); //strange bind of your code.
        } catch(e) {
            throw e;
        }
    }
}
Niels Steenbeek
  • 4,692
  • 2
  • 41
  • 50
  • Yeah I'd much prefer to do it this way. Haven't touched ES7 yet, scared to upgrade our codebase. The bind is in there because I haven't learned a new/better pattern for referencing class methods in my class. In this case connectDatabase is a method inside my class that then uses references to additional methods in the class. If I don't bind the method call to this, it loses it's context. Suggestions? – ddibiase Nov 14 '16 at 17:57
  • Can you please share some working sandbox? What if i do not want to listen if connectServer fails? – codeofnode May 29 '17 at 10:10
  • @codeofnode I updated my answer by adding try-catch. Your last question can be done by surrounding connectServer method by try-catch: try {await this.connectServer.bind(this);}catch(e){//don't throw to continue}. If you don't want to wait for connectServer, you can remove the await. – Niels Steenbeek May 29 '17 at 11:15