2723. Add Two Promises
Problem Description
In this problem, we are working with asynchronous operations in JavaScript, specifically with promises. A promise is an object representing the eventual completion or failure of an asynchronous operation. We are given two such objects, promise1
and promise2
, both of which are expected to resolve with a numerical value. The task is to create and return a new promise that will resolve with the sum of the two numbers provided by promise1
and promise2
.
Intuition
The key to solving this problem is understanding how promises work and how to handle the values they resolve with. The async
keyword allows us to write asynchronous code in a way that looks synchronous, and the await
keyword pauses the execution of the function until a promise is resolved. By using await
on both promise1
and promise2
, we can get their resolved values. Once both promises have been resolved, we can then simply add these two numerical values together. The sum is then implicitly returned as a resolved promise due to the async
function's behavior—any value returned by an async
function is automatically wrapped in a Promise.resolve()
.
So, the "intuition" behind this solution is:
- Wait for each promise to resolve using
await
. - Once both numbers are available, add them together.
- The
async
function will return a promise that resolves with the sum of the two numbers.
Solution Approach
The implementation of the solution is straightforward given the understanding of how JavaScript promises and async/await
work.
Here's a step-by-step breakdown of the algorithm:
-
An
async
function namedaddTwoPromises
is defined, which accepts two parameters:promise1
andpromise2
. Both parameters are expected to be promises that resolve to numbers. -
Inside the function, we use the
await
keyword beforepromise1
andpromise2
. This instructs JavaScript to pause the execution of the function until each promise resolves. Theawait
keyword can only be used within anasync
function. -
When
await promise1
is executed, the function execution is paused untilpromise1
is either fulfilled or rejected. If it's fulfilled, the resolved value (a number) is returned. Ifpromise1
is rejected, an error will be thrown, which can be caught usingtry...catch
blocks. -
Similarly,
await promise2
pauses the function execution untilpromise2
resolves, after which it provides the resolved value (a number). -
After obtaining both numbers, the function adds these two numbers together with the
+
operator. The expression(await promise1) + (await promise2)
computes the sum. -
The resulting sum is then returned from the
async
function. Because the function isasync
, this return value is automatically wrapped in a promise. Essentially,return (await promise1) + (await promise2);
is equivalent toreturn Promise.resolve((await promise1) + (await promise2));
.
The data structure used here is the built-in JavaScript Promise
, which is a proxy for a value that is not necessarily known when the promise is created. This lets asynchronous methods return values like synchronous methods: instead of immediately returning the final value, the asynchronous method returns a promise to supply the value at some point in the future.
The pattern used is async/await
, which is syntactic sugar over JavaScript Promises, providing a simpler and cleaner way to handle asynchronous operations. It allows for writing promise-based code as if it were synchronous, but without blocking the main thread.
This solution leverages the concurrency nature of promises to potentially execute both promise1
and promise2
at the same time, reducing the overall waiting time for both promises to resolve.
Therefore, the solution is concise, clear, and leverages modern JavaScript features to work with asynchronous operations effectively.
Ready to land your dream job?
Unlock your dream job with a 2-minute evaluator for a personalized learning plan!
Start EvaluatorExample Walkthrough
To illustrate the solution approach, let's walk through a small example using two sample promises that resolve to numerical values.
Suppose we have two promises:
const promise1 = new Promise((resolve, reject) => {
setTimeout(() => resolve(10), 1000); // promise1 resolves with 10 after 1 second
});
const promise2 = new Promise((resolve, reject) => {
setTimeout(() => resolve(20), 500); // promise2 resolves with 20 after 0.5 seconds
});
These promises, when executed, will resolve with the numbers 10 and 20, respectively, after their set timeouts.
Let's go through the steps of the solution with these promises:
- We define an
async
functionaddTwoPromises
that takespromise1
andpromise2
as parameters.
async function addTwoPromises(promise1, promise2) {
// The function body will be implemented according to the steps.
}
- We await both
promise1
andpromise2
using theawait
keyword inside theasync
function. This way we can get their resolved values:
async function addTwoPromises(promise1, promise2) {
const value1 = await promise1; // Execution pauses here until promise1 resolves.
const value2 = await promise2; // Execution pauses here until promise2 resolves.
// The rest of the function...
}
-
After both promises resolve,
value1
has the value 10, andvalue2
has the value 20. -
We then add
value1
andvalue2
and return the result:
async function addTwoPromises(promise1, promise2) {
const value1 = await promise1;
const value2 = await promise2;
return value1 + value2; // The function will return a Promise that resolves to 30
}
-
Since
addTwoPromises
is anasync
function, the returned result will be wrapped in a promise. Therefore, callingaddTwoPromises(promise1, promise2)
will return a promise that resolves to the sum of the two values, which is 30 in this case. -
If we want to use the result of the
addTwoPromises
function, we can do so by attaching a.then
method or using anawait
within anotherasync
function:
addTwoPromises(promise1, promise2).then(sum => {
console.log(sum); // This will log 30 to the console once the promise resolves
});
or,
async function displayResult() {
const result = await addTwoPromises(promise1, promise2);
console.log(result); // This will also log 30 to the console
}
And that concludes the example walkthrough of how to use the solution approach to add two numbers provided by promises asynchronously.
Solution Implementation
1import asyncio
2
3# Function that adds the values resolved from two futures.
4# Takes two futures that resolve to numbers as parameters.
5async def add_two_promises(future1, future2):
6 """
7 This coroutine waits for two futures to resolve and adds their results.
8
9 :param future1: A future (async result) that resolves to a number.
10 :param future2: A future (async result) that resolves to a number.
11 :return: The sum of the two numbers when both futures have resolved.
12 """
13 # Await the resolution of the first future and store the resulting value.
14 value1 = await future1
15
16 # Await the resolution of the second future and store the resulting value.
17 value2 = await future2
18
19 # Return the sum of the two values.
20 return value1 + value2
21
22# Example usage of the add_two_promises coroutine:
23# - Resolves two futures, each with the value 2, and logs the sum, which is 4.
24async def main():
25 result = await add_two_promises(asyncio.Future(), asyncio.Future())
26 print(result) # Expected output: 4
27
28# Initialize two futures and set their results to 2.
29future1 = asyncio.ensure_future(asyncio.sleep(0, result=2))
30future2 = asyncio.ensure_future(asyncio.sleep(0, result=2))
31
32# Run the main coroutine that utilizes the add_two_promises coroutine.
33asyncio.run(main())
34
1import java.util.concurrent.CompletableFuture;
2import java.util.concurrent.ExecutionException;
3
4// Class containing the method to add values from two CompletableFutures
5public class FutureAdder {
6
7 // Function that adds the values from two CompletableFutures.
8 // Takes two CompletableFutures that complete with numbers as parameters.
9 public static CompletableFuture<Integer> addTwoFutures(
10 CompletableFuture<Integer> future1,
11 CompletableFuture<Integer> future2) {
12
13 // Combine both futures to sum the resolved numbers once both are completed
14 return future1.thenCombine(future2, Integer::sum);
15 }
16
17 // Example usage of the addTwoFutures method
18 public static void main(String[] args) {
19 CompletableFuture<Integer> completableFuture1 = CompletableFuture.supplyAsync(() -> 2);
20 CompletableFuture<Integer> completableFuture2 = CompletableFuture.supplyAsync(() -> 2);
21
22 // Compute the sum of both future's results
23 CompletableFuture<Integer> sumFuture = addTwoFutures(completableFuture1, completableFuture2);
24
25 // Log the result once computation is complete
26 sumFuture.thenAccept(System.out::println) // Expected output: 4
27 .exceptionally(ex -> { // In case of an exception, cope with it here
28 System.out.println("An error occurred: " + ex.getMessage());
29 return null;
30 });
31 // To ensure that the application does not terminat before completing the future computation
32 // Handle with care as it may cause the application to hang if futures don't complete
33 try {
34 sumFuture.get();
35 } catch (InterruptedException | ExecutionException ex) {
36 ex.printStackTrace();
37 }
38 }
39}
40
1#include <iostream>
2#include <future>
3#include <functional>
4
5// Function that adds the values obtained from two futures.
6// Takes two futures that will provide numbers as parameters.
7std::future<int> addTwoFutures(std::future<int>&& future1, std::future<int>&& future2) {
8 // Create a new std::promise<int> that will eventually hold the result
9 std::promise<int> result_promise;
10
11 // Get the std::future<int> associated with the result_promise
12 std::future<int> result_future = result_promise.get_future();
13
14 // Lambda that processes the addition of two future values
15 auto compute = [](std::future<int>&& future1, std::future<int>&& future2, std::promise<int> result_promise) mutable {
16 // Wait for the first future to be ready and get its value
17 int value1 = future1.get();
18
19 // Wait for the second future to be ready and get its value
20 int value2 = future2.get();
21
22 // Set the promise's value to the sum of the two obtained values
23 result_promise.set_value(value1 + value2);
24 };
25
26 // Start asynchronous execution
27 std::async(std::launch::async, compute, std::move(future1), std::move(future2), std::move(result_promise));
28
29 // Return the future that will provide the sum
30 return result_future;
31}
32
33// Example usage of the addTwoFutures function
34// - Resolves two futures, each with the value 2, and logs the sum, which is 4.
35int main() {
36 // Create two promises
37 std::promise<int> promise1;
38 std::promise<int> promise2;
39
40 // Set values to the promises
41 promise1.set_value(2);
42 promise2.set_value(2);
43
44 // Get futures from promises
45 std::future<int> future1 = promise1.get_future();
46 std::future<int> future2 = promise2.get_future();
47
48 // Call addTwoFutures with the futures we got from the promises
49 std::future<int> result = addTwoFutures(std::move(future1), std::move(future2));
50
51 // Wait for the result future to be ready and get its value, then print
52 std::cout << "Expected output: " << result.get() << std::endl; // Expected output: 4
53
54 return 0;
55}
56
1// Function that adds the values resolved from two promises.
2// Takes two promises that resolve to numbers as parameters.
3async function addTwoPromises(
4 promise1: Promise<number>,
5 promise2: Promise<number>,
6): Promise<number> {
7 // Await the resolution of the first promise and store the resulting value.
8 const value1 = await promise1;
9
10 // Await the resolution of the second promise and store the resulting value.
11 const value2 = await promise2;
12
13 // Return the sum of the two values.
14 return value1 + value2;
15}
16
17// Example usage of the addTwoPromises function:
18// - Resolves two promises, each with the value 2, and logs the sum, which is 4.
19addTwoPromises(Promise.resolve(2), Promise.resolve(2))
20 .then(console.log); // Expected output: 4
21
Time and Space Complexity
Time Complexity
The time complexity of the function addTwoPromises
largely depends on how promise1
and promise2
resolve. However, since it is awaiting both promises one after the other, it will be at least as long as the longest time taken for either of the promises to resolve. If the promises do not depend on each other and could resolve in parallel, this sequential waiting increases the total time unnecessarily. Therefore, if T1
is the time taken for promise1
to resolve and T2
is the time taken for promise2
to resolve, the time complexity would be O(T1 + T2)
where T1
and T2
are the respective completion times for each promise. If promise1
and promise2
were to be awaited in parallel, the time complexity could be improved to O(max(T1, T2))
.
Space Complexity
The space complexity of the function addTwoPromises
itself is O(1)
, as it only needs the space for two number variables when the promises resolve, and one number for the return value. There is no additional space being used that scales with the size of the input.
Which type of traversal does breadth first search do?
Recommended Readings
LeetCode Patterns Your Personal Dijkstra's Algorithm to Landing Your Dream Job The goal of AlgoMonster is to help you get a job in the shortest amount of time possible in a data driven way We compiled datasets of tech interview problems and broke them down by patterns This way we
Recursion Recursion is one of the most important concepts in computer science Simply speaking recursion is the process of a function calling itself Using a real life analogy imagine a scenario where you invite your friends to lunch https algomonster s3 us east 2 amazonaws com recursion jpg You first
Runtime Overview When learning about algorithms and data structures you'll frequently encounter the term time complexity This concept is fundamental in computer science and offers insights into how long an algorithm takes to complete given a certain input size What is Time Complexity Time complexity represents the amount of time
Want a Structured Path to Master System Design Too? Don’t Miss This!