Javascript Tricky Promises Related Questions — NodeJs
Question 1:
Predict the output.
const promise = new Promise((resolve, reject) => {
reject(Error('Error occurred'));
});
promise.catch(error => console.log(error.message));
promise.catch(error => console.log(error.message));
Output:
Explanation:
- A Promise is created and immediately rejected with the error message ‘Error occurred’.
- Two
catch
handlers are attached to the Promise, and each logs the error message to the console when the Promise is rejected. - Since the Promise is rejected, both
catch
handlers will be executed, resulting in the error message being logged twice.
Question 2:
Guess the output.
Output:
Explanation:
- The
console.log('start')
statement is executed first, logging "start" to the console. - The
Promise
constructor is invoked, but it doesn't contain any asynchronous operation or a call to eitherresolve
orreject
. So, theconsole.log(1)
statement inside thePromise
constructor is executed synchronously. - Finally,
console.log('end')
is executed, logging "end" to the console.
Keep in mind that without asynchronous operations or calls to resolve
or reject
inside the Promise
constructor, the promise is considered immediately resolved, and its behavior is synchronous.
Question 3:
What is the output of this code snippet?
Output:
Explanation:
- The
performTask
function returns a Promise that is immediately rejected. - The first three
.then()
blocks are skipped because the Promise is rejected. - The
.catch()
block catches the rejection and logs 'Error 1'. - Despite the error, the final
.then()
block is still executed, logging 'Success 4' to the console. This behavior is due to the fact that.catch()
only catches errors in the preceding Promise chain, and subsequent.then()
blocks are executed regardless of previous errors.
Question 4:
Given the following code, what will be the final output?
const promise = new Promise((resolve) => {
resolve(1);
});
promise.then((value) => {
console.log(value);
return value + 1;
}).then((value) => {
console.log(value);
throw new Error('Something went wrong');
}).catch((error) => {
console.error(error.message);
});
Output:
1
2
Something went wrong
Explanation:
- The first
.then()
logs1
to the console and returnsvalue + 1
, which is2
.
2. The second .then()
logs 2
to the console and then intentionally throws an error.
3. The error is caught by the .catch()
block, and the error message 'Something went wrong' is logged to the console.
This code illustrates the chaining of asynchronous operations with Promises and how errors in the chain are caught by the .catch()
block.
Question 5:
What is the output of the following code?
var promise = new Promise(function(resolve, reject){
setTimeout(function() {
resolve('Resolved!');
}, 1000);
});
promise.then(function(value) {
console.log(value)
});
Expected Output (after approximately 1 second):
Explanation:
- The
setTimeout
introduces a delay, making the Promise resolve after 1000 milliseconds. - When the Promise is resolved, the
.then()
block is executed, and the resolved value ('Resolved!') is logged to the console.
This code demonstrates how Promises can be used to handle asynchronous operations and how the .then()
method is employed to handle the resolution of the Promise.
Question 6:
What is the output of the following code?
Output:
1
2
4
Explanation:
- The
setTimeout
introduces a delay of 1000 milliseconds before resolving the Promise with the value1
. - Each
.then()
block performs an operation on the previous result and logs the updated value. - The chaining of
.then()
handlers allows for sequential processing of the asynchronous results.
Question 7:
What is the output of the following code?
console.log('Start');
setTimeout(() => {
console.log('Timeout');
}, 0);
Promise.resolve().then(() => {
console.log('Promise resolved');
});
console.log('End');
Output:
Explanation:
console.log('Start');
: Synchronous operation, logs "Start" to the console.setTimeout(() => { console.log('Timeout'); }, 0);
: Asynchronous operation usingsetTimeout
. Even though the timeout is set to 0 milliseconds, it will still be executed after the current synchronous code has finished. Logs "Timeout" to the console.Promise.resolve().then(() => { console.log('Promise resolved'); });
: Asynchronous operation using a resolved Promise. This will be executed in the next tick of the event loop after the current synchronous code. Logs "Promise resolved" to the console.console.log('End');
: Synchronous operation, logs "End" to the console.
Question 8:
What is the output of this code snippet?
let firstTask = new Promise(function(resolve, reject) {
setTimeout(resolve, 500, 'Task One');
});
let secondTask;
let thirdTask = new Promise(function(resolve, reject) {
setTimeout(resolve, 1200, 'Task Three');
});
let fourthTask = new Promise(function(resolve, reject) {
setTimeout(reject, 300, 'Task Four');
});
let fifthTask = new Promise(function(resolve, reject) {
setTimeout(resolve, 1000, 'Task Two');
});
let combinedPromise = Promise.all([firstTask, secondTask, thirdTask, fourthTask, fifthTask]);
combinedPromise
.then(function(data) {
data.forEach(function(value) {
console.log('Result:', value);
});
})
.catch(function(error) {
console.error('Error:', error);
});
Output:
Explanation:
- The
firstTask
resolves after 500 milliseconds with the value'Task One'
. - The
secondTask
is uninitialized, so it is treated as a resolved promise with the valueundefined
. - The
thirdTask
resolves after 1200 milliseconds with the value'Task Three'
. - The
fourthTask
is set to reject after 300 milliseconds with the value'Task Four'
. - The
fifthTask
resolves after 1000 milliseconds with the value'Task Two'
.
Question 9:
What is the output of the following code?
const promise1 = new Promise(resolve => setTimeout(resolve, 100, 'One'));
const promise2 = new Promise(resolve => setTimeout(resolve, 200, 'Two'));
Promise.race([promise1, promise2])
.then(value => console.log(value))
.catch(error => console.error(error));
Output:
Explanation:
- Two promises (
promise1
andpromise2
) are created withsetTimeout
to simulate asynchronous operations. - The
Promise.race
is used to resolve or reject with the first settled promise (either resolved or rejected). - In this case,
promise1
settles first (after 100 milliseconds), so the.then
block is executed, logging 'One' to the console. - The
.catch
block is not triggered because there are no rejections.
Question 10:
What is the output of the following code?
const promise1 = Promise.resolve(1);
const promise2 = new Promise(resolve => setTimeout(resolve, 200, 2));
const promise3 = new Promise((resolve, reject) => setTimeout(reject, 100, 'Error'));
Promise.all([promise1, promise2, promise3])
.then(values => console.log(values))
.catch(error => console.error(error));
Output:
In the provided code, you are using Promise.all
to handle an array of promises. Here's the expected output:
Explanation:
1. promise1
is resolved immediately with the value 1
.
2. promise2
is resolved after a timeout of 200 milliseconds with the value.
3. promise3
is rejected after a timeout of 100 milliseconds with the reason 'Error'
.
The Promise.all()
method takes an array of promises as an argument and returns a new promise that is fulfilled with an array of the fulfilled values when all promises in the iterable argument have been fulfilled. If any of the promises in the iterable are rejected, the resulting promise is rejected with the reason of the first promise that was rejected.
Since one of the promises (promise3
) is rejected, the Promise.all()
promise is rejected, and the catch
block is executed. Therefore, the output of the code will be Error
:
Question 11:
What is the output of the following code?
Promise.resolve(1)
.then(value => {
console.log(value);
return Promise.resolve(2);
})
.then(value => console.log(value));
Output:
Explanation:
1. Promise.resolve(1)
creates a promise that immediately resolves with the value 1
.
2. The first .then()
block logs the resolved value 1
to the console and returns a new promise (Promise.resolve(2)
).
3. The second .then()
block logs the resolved value 2
to the console.
Conclusion :
In conclusion, mastering promises in Node.js is vital for proficient asynchronous programming. Understanding promise chaining, order of execution, and nuances like Promise.all
and Promise.race
is essential. Effective error handling through catch
and finally
ensures robust code. The advent of async/await simplifies asynchronous code, offering a more synchronous appearance. Unhandled promise rejections may lead to warnings or errors, emphasizing the importance of proper error management. Asynchronous operations can be orchestrated with precision, enabling developers to create efficient and responsive applications. With these principles, developers can navigate the intricacies of promises, fostering code that is both reliable and performance-driven.
Here are some additional high-quality tutorials for you to explore: