Reputation: 547
I have a code that looks something like this
class foo {
constructor() {
// calling a, b, c synchronously
a().then(
function(response) {
b().then(
function(response) {
c();
}, function(error) {
// pass
}
);
}, function(error) {
// pass
}
);
}
a() {
return new Promise(function(fullfill, reject) {
// x is any function that returns a promise, making the
// implementation of this function "a" asynchronous
x().then(
function(response) {
fullfill(response);
}, function(error) {
reject(error);
}
);
});
}
b() {
return new Promise(function(fullfill, reject) {
// x is any function that returns a promise, making the
// implementation of this function "b" asynchronous
x().then(
function(response) {
fullfill(response);
}, function(error) {
reject(error);
}
);
});
}
c() {
// do something
}
}
Basically, I have two functions a
and b
which are both asynchronous.
These functions are asynchronous because they both call some function x
which returns a promise (in my case, it is a query to a database).
I need to call a
, followed by b
followed by c
but sequentially. One way of doing so is what I have implemented in the code above, but it results in nasty nested promise responses.
Is there any other way that I can achieve this same result, without using the following syntax (because if this is the only possible solution, then I might as well not use it at all).
Upvotes: 1
Views: 3581
Reputation: 7
Let seq = [f1,f2,...,fn] be a sequence of zero-argument promise returning functions. Build a promise p that will execute them sequentially with fi invoked after f{i-1}.
var p = seq.reduce( (p_acc,f) => p_acc.then( ()=>f() ) )
Then you probably want to do
p.catch(...)
Upvotes: 0
Reputation: 4787
Use promise chaining as shown below:
a().then(resA => {
// resA is response of function a()
// Do whatever you want with resA here
// and then return promise of function b()
return b();
})
.then(resB => {
// resB is response of function b()
// Do whatever you want with resA here
// and then return promise of function c()
return c();
})
.then(resC => {
// resC is response of function c()
// Do whatever you want with resC here
})
.catch(err => {
// Handle any reject/error of functions a, b or c
});
If you want to carry the response of function a and b till the end then you can do the chaining as follows:
a().then(resA => {
// resA is response of function a()
// Do whatever you want with resA here
// and then return promise of function b()
return b().then(resB => { resA: resA, resB: resB });
})
.then(res => {
// res is a object with rsponse of function a() & b()
// res.resA is response of function a()
// res.resB is response of function b()
// Do whatever you want to with the responses here
// then return promise of function c()
return c().then(resC, { resA: res.resA, resB: res.resB, resC: resC });
})
.then(resC => {
// res is a object with rsponse of function a(), b() & c()
// res.resA is response of function a()
// res.resB is response of function b()
// res.resC is response of function c()
// Do whatever you want to with the responses
})
.catch(err => {
// Handle any reject/error of functions a, b or c
});
The above code is elaborate for demo/explanation. It can be reduced with ES6 as shown below
a().then(resA => {
// resA is response of function a()
// Do whatever you want with resA here
// and then return promise of function b()
return b().then(resB => { resA, resB });
})
.then(res => {
// res is a object with rsponse of function a() & b()
// res.resA is response of function a()
// res.resB is response of function b()
// Do whatever you want to with the responses here
// then return promise of function c()
return c().then(resC, Object,assign(res, { resC }));
})
.then(resC => {
// res is a object with rsponse of function a(), b() & c()
// res.resA is response of function a()
// res.resB is response of function b()
// res.resC is response of function c()
// Do whatever you want to with the responses
})
.catch(err => {
// Handle any reject/error of functions a, b or c
});
Hope this helps.
Upvotes: 2