sandrooco
sandrooco

Reputation: 8776

JS Promise: control flow

I have to set a few things up via an API. It's important that the different functions are executed after each other. All of the listed functions return a proper promise.

a(analyticsConfig._listConfig)
    .then(function() {
        return b(listName, analyticsConfig._fieldConfig);
    })
    .then(function() {
        return c(listName)
    })
    .then(function() {
        return d(analyticsConfig._roleConfig);
    })

I'd like to use something like a.then(b(listName, analyticsConfig._fieldConfig)) or so but as you probably know this won't work.

Is there another way to do this?

Upvotes: 1

Views: 402

Answers (4)

m0meni
m0meni

Reputation: 16455

You can write it as

a.then(b.bind(null, listName, analyticsConfig._fieldConfig))

or, if you're either using babel to transpile your code, or you're targeting a version of node > v4., you can do

a.then(() => b(listName, analyticsConfig._fieldConfig))

Upvotes: 2

Gorka Hernandez
Gorka Hernandez

Reputation: 3968

You can do the following using async/await:

function a() {
    console.log('Getting A...');
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve('Hello A!');
        }, 1000);
    });
}

function b() {
    console.log('Getting B...');
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve('Hello B!');
        }, 1000);
    });
}

function c() {
    console.log('Getting C...');
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve('Hello C!');
        }, 1000);
    });
}

function d() {
    console.log('Getting D...');
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve('Hello D!');
        }, 1000);
    });
}

async function getAll() {
    await a();
    await b();
    await c();
    await d();
    console.log('Done');
}

Upvotes: -1

apokryfos
apokryfos

Reputation: 40730

You can bind it:

a.then(b.bind(context,listName,analyticsConfig._fieldConfig))

Be sure to bind the expected context to it though.

According to the docs:

The bind() method creates a new function that, when called, has its this keyword set to the provided value, with a given sequence of arguments preceding any provided when the new function is called.

Upvotes: 1

Bergi
Bergi

Reputation: 665574

That will only work if b returns a function that returns a promise. You always must pass a function to then as the callback, there's no way around that. There are however many ways to construct one.

Leaving partial application (with bind or other), currying and such stuff aside, your best options for nicer syntax are ES8 async/await

(async function() {
    await a(analyticsConfig._listConfig);
    await b(listName, analyticsConfig._fieldConfig);
    await c(listName);
    await d(analyticsConfig._roleConfig);
})();

or ES6 arrow functions:

a(analyticsConfig._listConfig)
.then(() => b(listName, analyticsConfig._fieldConfig))
.then(() => c(listName))
.then(() => d(analyticsConfig._roleConfig))

Upvotes: 4

Related Questions