Reputation: 1658
In this code:
new Promise((resolve, reject) => {
DB.get(params, function(err, data) {
if (err) reject(err)
else resolve(data.Item)
})
})
.then((data) => {
let params = { Name: 'DEMO' }
CWevents.putRule(params, function(err, data) {
if (err) console.log("Error", err)
else console.log("Success")
})
})
.then(() => {
let params = { Rule: 'DEMO' }
CWevents.putTargets(params, function(err, data) {
if (err) console.log("Error", err)
else console.log("Success", data)
})
})
The DB.get
function here has a callback, but it would look awful to put multiple callbacks into each other, so I decided to use promises. I create a new promise, inside which is an asynchronous function. After it finishes running, it resolves and the first .then
starts working, as desired. Then inside that first .then
I have another asynchronous function that works much like the first one.
But there's no resolve/reject
to run this time. So the third .then
runs before the function inside second .then
is finished. How can I make the third .then
wait until the second one finished running? So function 1 finishes running, then function 2, then 3?
Upvotes: 0
Views: 2136
Reputation: 147
You could wrap the CWEvents.putRule
call inside a Promise. Then you can call the resolve or reject of the promise from CWEvents.putRule
. This can be captured by a then
or error
Your code should look like this
new Promise((resolve, reject) => {
DB.get(params, function(err, data) {
if (err) reject(err);
else resolve(data.Item);
});
})
.then(data => { // data not needed as you are not using it in the remaining code
let params = { Name: "DEMO" };
return new Promise((resolve, reject) => {
CWevents.putRule(params, function(err, data) {
if (err) {
console.log("Error", err);
reject(err)
} else {
console.log("Success");
resolve() // resolve(data) if you want to pass the data from CWEvents.putRule
}
});
});
})
.then(() => {
let params = { Rule: "DEMO" };
CWevents.putTargets(params, function(err, data) {
if (err) console.log("Error", err);
else console.log("Success", data);
});
});
You could do the same thing in a much more readable way using async await
async function process() {
try {
var data = new Promise((resolve, reject) => {
DB.get("params", function(err, data) {
if (err) reject(err);
else resolve(data.Item);
});
}); // this will return a promise to the variable data
var response = (function processData(data) {
let params = { Name: "DEMO" };
return new Promise((resolve, reject) => {
CWevents.putRule(params, function(err, data) {
if (err) {
console.log("Error", err);
reject(err);
} else {
console.log("Success " + data.Item);
resolve(data);
}
});
});
})(await data);
/* by using the await keyword , we can wait for the promise to be complete before moving on to the next step
of execution.
*/
/*
* waiting on the response promise to complete
*/
if (await response) {
let params = { Rule: "DEMO" };
CWevents.putTargets(params, function(err, data) {
if (err) console.log("Error", err);
else console.log("Success", data);
});
}
} catch (e) {
console.log("Error occured during operation " + e);
}
}
process();
You can find more details about async await
on MDN
Upvotes: 1
Reputation: 1658
I've found a solution. Inside a .then
you can create a new Promise and return it to the next .then
, like this
new Promise((resolve, reject) => {
setTimeout(() => {resolve(1)}, 1000)
})
.then((message) => {
console.log(message)
return new Promise((resolve, reject) => {
setTimeout(() => {resolve(2)}, 5000)
})
})
.then((message) => {
console.log(message)
return new Promise((resolve, reject) => {
setTimeout(() => {resolve(3)}, 1000)
})
})
This will chain them together synchronously, so the output will be 1, 2, then 3. Without the construction it would output 1 and 3 at the same time, and then 2.
Upvotes: 0