How to execute functions sequentially using Node Js Promise? - javascript

I'm new to Node js Promise I'm not sure whether I'm using the Promise correctly or not so here is my code.
function print(){
first('first')
.then(second('second'))
.then(third('third'));
}
function first(a){
return new Promise((resolve, reject) => {
var res1 = function (){
resolve(a);
}
});
console.log(a);
}
function second(b){
return new Promise((resolve, reject) => {
var res1 = function (){
resolve(b);
}
});
setTimeout(() => {
console.log(b);
}, 2000);
}
function third(c){
return new Promise((resolve, reject) => {
var res1 = function (){
resolve(c);
}
});
console.log(c);
}
My desired output is
first
second
third
Instead what I get is
first
third
//after two seconds
second
I'm missing something but I can't figure it out please explain me

To get the expected behaviour, you need to resolve inside of the timeout (next to the console log). You also cannot pass arguments into promise chain functions since they need to accept the promise from the previous thennable.
A working snippet is below:
print();
function print(){
first('first')
.then(second)
.then(third);
}
function first(a){
return new Promise((resolve, reject) => {
console.log(a);
resolve(a);
});
}
function second(b){
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log("second");
resolve(b);
}, 2000);
});
}
function third(c){
return new Promise((resolve, reject) => {
console.log("third");
resolve(c)
});
}

Related

How does Javascript Promise work with setTimeOut [duplicate]

This question already has answers here:
Why does the `then()` handler of a promise execute immediately?
(3 answers)
Closed last month.
I apologize if this is a basic question. I am really puzzled by how Promise works in Javascript.
I have the following piece of code:
function wait(ms) {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log("Done waiting");
resolve(ms);
}, ms);
});
}
let a = true;
let p = new Promise(async (resolve, reject) => {
await wait(3000);
console.log("Inside Promise");
if (a) {
resolve("Success");
} else {
reject("Failure");
}
});
const func = async () => {
let output = await p;
console.log(output);
};
func().then(console.log("abc"));
This is the printout:
abc
Done waiting
Inside Promise
Success
I cannot, for the life of me, figure out why abc is printed first. Shouldn't it wait for func() to finish executing? I expected abc to be printed last. Can anyone walk me through the steps of execution? Thanks in advance. I would really appreciate it.
What you've provided to Promise.then is not a callback and it is evaluated immediately at runtime. You need to move the console.log into the body of the function instead:
func().then(() => console.log("abc"));
See working example below:
function wait(ms) {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log("Done waiting");
resolve(ms);
}, ms);
});
}
let a = true;
let p = new Promise(async (resolve, reject) => {
await wait(3000);
console.log("Inside Promise");
if (a) {
resolve("Success");
} else {
reject("Failure");
}
});
const func = async () => {
let output = await p;
console.log(output);
};
func().then(() => console.log("abc"));

Javascript execute function after Promise.all

I have a set of functions in a promise and after all of them have been executed I need to call a specific function that used the results obtained from each function. This is the code:
async function returnValues() {
var finalVal1;
function returnValue1() {
return new Promise((resolve, reject) => {
finalVal1 = {};
//do stuff
return finalVal1;
})
}
var finalVal2;
function returnValue2() {
return new Promise((resolve, reject) => {
finalVal2 = {};
//do stuff
return finalVal2;
})
}
var finalVal3;
function returnValue3() {
return new Promise((resolve, reject) => {
finalVal3 = {};
//do stuff
return finalVal3;
})
}
var finalVal4;
function returnValue4() {
return new Promise((resolve, reject) => {
finalVal4 = {};
//do stuff
return finalVal4;
})
}
let promise = await Promise.all([returnValue1(), returnValue2(), returnValue3(), returnValue4()]).then(myFunction(finalVal1, finalVal2, finalVal3, finalVal4));
}
function myFunction(finalVal1, finalVal2, finalVal3, finalVal4) {
console.log(finalVal1);
console.log(finalVal2);
console.log(finalVal3);
console.log(finalVal4);
}
The problem is that every returnVal() function is working perfectly fine, and the myFunction() work fine if I'm calling them separately, but when I'm using the Promise.all it never executes the myFunction() bit.
Where am I wrong?
Thank you very much
Try like this :
Simplified "function that returns a Promise" to a constant.
Promises do resolve()
The result of await Promise.all is an array of values, this array is passed to myFunction
async function returnValues() {
const returnValue1 = new Promise((resolve, reject) => {
let finalVal1 = {};
//do stuff
resolve(finalVal1);
});
const returnValue2 = new Promise((resolve, reject) => {
let finalVal2 = {};
//do stuff
resolve(finalVal2);
})
}
const values = await Promise.all([returnValue1, returnValue2])
myFunction(values);
}
function myFunction(values) {
console.log(values[0]);
console.log(values[1]);
}

Putting up delay in promises

So, I have two promises that I want to print on screen with a 3sec delay in between. How would I achieve it. Below is the code.
const promiseOne = new Promise(function(resolve, reject) {
resolve("Hello")
});
const promiseTwo = new Promise(function(resolve, reject) {
resolve("Good Morning")
});
Promise.all([promiseOne, promiseTwo]).then(function() {
setTimeout(() => {
const response = Promise.all.next();
console.log(response);
}, 3000);
});
I suggest you use a delay function. First you loop through each response in the array and use the delay in between
const promiseOne = new Promise(function(resolve, reject) {
resolve("Hello")
});
const promiseTwo = new Promise(function(resolve, reject) {
resolve("Good Morning")
});
function delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
Promise.all([promiseOne, promiseTwo]).then(async function(resps) {
for(let res of resps){
console.log(res);
await delay(3000)
}
});
const promiseOne = new Promise(function(resolve, reject) {
resolve("Hello")
});
const promiseTwo = new Promise(function(resolve, reject) {
resolve("Good Morning")
});
Promise.all([promiseOne, promiseTwo]).then(function(all) {
return new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve(all);
}
, 3000);
});
}).then(console.log)
Return new Promise in then, that promise waits for x millisecond and resolve it.
And do anything in next then
If you just want to delay the log then you can add response parameter as explained by #Daniel Rodríguez Meza.
But if you want to delay response from any one of the promise promiseOne or promiseTwo then you should use setTimeout(() => resolve("Hello"), 300); inside respective promise as shown below. Also do not use setTimeout inside Promise.All.
As per OP's comment I have updated answer to resolve promiseTwo 3 seconds after promiseOne resolves.
Here I've assigned resolve of promiseTwo to global variable resolvePromiseTwo which is used inside promiseOne to resolve promiseTwo after 3 seconds.
Note I have used .then after promiseOne and promiseTwo just to verify output. You can omit both.
let resolvePromiseTwo = null;
const promiseOne = new Promise(function(resolve, reject) {
resolve("Good Morning")
setTimeout(() => resolvePromiseTwo("Hello"), 3000);
}).then(res => {
console.log('promiseOne resolved');
return res;
});
const promiseTwo = new Promise(function(resolve, reject) {
resolvePromiseTwo = resolve;
}).then(res => {
console.log('promiseTwo resolved');
return res;
});
Promise.all([promiseOne, promiseTwo]).then(function(response) {
console.log('Promise.all');
console.log(response);
});
You were pretty close, you just need to receive the value from the results of the Promise.all and then handle that information, like this:
const promiseOne = new Promise(function(resolve) {
resolve("Hello")
});
const promiseTwo = new Promise(function(resolve) {
resolve("Good Morning");
});
Promise.all([promiseOne, promiseTwo])
.then(function(response) {
setTimeout(() => {
console.log(response);
}, 3000);
});
Edit
According to the clarification given by OP what he needs is the following:
After the first promise is resolved, wait 3 seconds and then execute the second promise.
const promiseOne = new Promise(function(resolve) {
resolve("Hello")
});
const promiseTwo = new Promise(function(resolve) {
resolve("Good Morning");
});
async function resolveWithDelay(delay = 3000) {
const res1 = await promiseOne;
console.log(res1);
setTimeout(async () => {
const res2 = await promiseTwo;
console.log(res2);
}, delay);
}
resolveWithDelay();

Promise.All function invocation issue

I'm using Promise.all function to resolve the multiple promises concurrently. See the below code -
function check1() {
console.log('check 1 invoked')
return new Promise((resolve, reject) => {
setTimeout(()=> resolve('check1'), 4000);
})
}
function check2() {
console.log('check2 invoked')
return new Promise((resolve, reject) => {
setTimeout(()=> resolve('check2'), 4000);
})
}
var arr = [check1(), check2()];
Promise.all(arr)
.then((response) => console.log('response======>',response))
.catch((error) => console.error('error',error))
The problem with the above approach is that when I create the promise array, The respective functions gets invoked. I want to change the above code in the manner that two functions call only from the promise.all function.
Note - Need to store the promises functions in the array. Like I'm doing as var arr.
This should do it, do not make an array of promises but an array of functions, then map the functions to promises:
function check1() {
console.log('check 1 invoked')
return new Promise((resolve, reject) => {
setTimeout(()=> resolve('check1'), 4000);
})
}
function check2() {
console.log('check2 invoked')
return new Promise((resolve, reject) => {
setTimeout(()=> resolve('check2'), 4000);
})
}
//do not store the promises, store the funciton that creates a promise
var arr = [check1, check2];
Promise.all(
//map functions to promises
arr.map(fn=>fn())
)
.then((response) => console.log('response======>',response))
.catch((error) => console.error('error',error))
You can do in this way too -
var check1 = new Promise((resolve, reject) => {
setTimeout(()=> resolve('check1'), 4000);
});
var check2 = new Promise((resolve, reject) => {
setTimeout(()=> resolve('check2'), 4000);
});
Promise.all([check1, check2]).then(values => {
console.log(values);
}, reason => {
console.log(reason)
});

Promise.all is not displaying the data

I am new to promises and I want to return the data from classes as promises. I have two classes with two function in each class. What I am doing each function is returning a promise from a class, but I am unable to execute promise.all. Below is the code
Class1
class TestClass {
firstPromise() {
return new Promise((resolve, reject) => {
resolve('return first promise')
})
}
secondPromise() {
return new Promise((resolve, reject) => {
resolve('return second promise')
})
}
}
module.exports.TestClass = TestClass;
Class2
class TestClass1 {
firstPromise() {
return new Promise((resolve, reject) => {
resolve('return first promise')
})
}
secondPromise() {
return new Promise((resolve, reject) => {
resolve('return second promise')
})
}
}
module.exports.TestClass1 = TestClass1;
Main function
let data = req.body;
let test1Object;
let testObject;
let testParam;
let testParam1;
if (data.hasOwnProperty('param1')) {
test1Object = new test1.TestClass1();
test1Object.firstPromise().then((data)=>{
testParam1 = test1Object.secondPromise();
});
}
if (data.hasOwnProperty('param2')) {
testObject = new test.TestClass();
testObject.firstPromise().then((data)=>{
testParam = testObject.secondPromise()
});
}
Promise.all([testParam,testParam1]).then((data)=>{
console.log(data)
});
it displays
[ undefined, undefined ]
When you're executing Promise.all(), the promises are not yet resolved, so testParam and testParam1 are undefined. I think you should assign the first promise to testParam1:
testParam1 = test1Object.firstPromise().then(data => test1Object.secondPromise());
and similarly the second to testParam:
testParam = testObject.firstPromise().then(data => testObject.secondPromise());

Categories