[Leetcode] JS 30 Add two promises

[Leetcode] JS 30 Add two promises

Question

Given two promises promise1 and promise2, return a new promise. promise1 and promise2 will both resolve with a number. The returned promise should resolve with the sum of the two numbers.

Example 1:

Input:
promise1 = new Promise(resolve => setTimeout(() => resolve(2), 20)),
promise2 = new Promise(resolve => setTimeout(() => resolve(5), 60))
Output: 7
Explanation: The two input promises resolve with the values of 2 and 5 respectively. The returned promise should resolve with a value of 2 + 5 = 7. The time the returned promise resolves is not judged for this problem.

Example 2:

Input:
promise1 = new Promise(resolve => setTimeout(() => resolve(10), 50)),
promise2 = new Promise(resolve => setTimeout(() => resolve(-12), 30))
Output: -2
Explanation: The two input promises resolve with the values of 10 and -12 respectively. The returned promise should resolve with a value of 10 + -12 = -2.

Constraints:

  • promise1 and promise2 are promises that resolve with a number

My Solution

/**
 * @param {Promise} promise1
 * @param {Promise} promise2
 * @return {Promise}
 */
var addTwoPromises = async function(promise1, promise2) {
    let num1 = await promise1;
    let num2 = await promise2;
    return num1 + num2
};

/**
 * addTwoPromises(Promise.resolve(2), Promise.resolve(2))
 *   .then(console.log); // 4
 */

Key Takeaways

What’s Promise?

A Promise is an object representing the eventual completion (or failure) of an asynchronous operation, such as making an HTTP request or reading a file.

  • Pending: The initial state of a Promise, indicating that the operation has not been completed yet.
  • Fulfilled: The operation was successfully completed, and the Promise resolved with a value.
  • Rejected: The operation failed, and the Promise was rejected with an error.

Syntax Logic

Promise constructor takes a function with two parameters: resolve and reject. After setting Promise functions, we can use Promise.then().catch() to handle results.

  • resolve(value): Marks the Promise as fulfilled and returns the specified value.
  • reject(error): Marks the Promise as rejected and returns an error.
const myPromise = new Promise((resolve, reject) => {
    setTimeout(() => {
        let success = true;
        if (success) {
            resolve("Success!");
        } else {
            reject("Fail!");
        }
    }, 2000);
});

// use then to handle success while catch handles failures
myPromise
    .then(result => console.log(result))  // "Success!"
    .catch(error => console.error(error)); // if fail, will print "Fail!

But if we need to call Promise.then().catch() every time, it seems too bothering. So this is where sugar syntax async await comes in place.

More about Promise

Promise.all() allows multiple Promise instances to execute in parallel. It resolves when all Promises are fulfilled and rejects if any Promise fails.

var addTwoPromises = async function(promise1, promise2) {
	let [num1, num2] = await Promise.all([promise1, promise2]);
   return num1 + num2
};

What is Async/Await ?

Async Function

  • async is used to define functions that always return a Promise, even if the function returns a regular value.
  • Inside async functions we can use await to wait for Promise being solved.

Await

  • await can only be used within async functions.
  • await pauses execution until the Promise resolves, returning its value. If the Promise is rejected, an error is thrown."

Example:

async function fetchData() {
    try {
        let response = await fetch('<https://jsonplaceholder.typicode.com/todos/1>');
        let data = await response.json();
        console.log(data);
    } catch (error) {
        console.error("Error:", error);
    }
}

fetchData();

Difference between traditional Promise and Async/Await

Compared to traditional Promise syntax, async/await is more readable, easier to understand, and allows better error handling using try...catch. It also avoids the nesting issue caused by multiple .then() calls.

Traditional Promise

function fetchData() {
    fetch('<https://jsonplaceholder.typicode.com/todos/1>')
        .then(response => response.json())
        .then(data => console.log(data))
        .catch(error => console.error("Error:", error));
}

fetchData();

Sugar SyntaxAsync/Await

  • async/await makes codes more intuitive and more readable.
  • Easier to handle mistakes since we can use try...catch
async function fetchData() {
    try {
        let response = await fetch('https://jsonplaceholder.typicode.com/todos/1');
        let data = await response.json();
        console.log(data);
    } catch (error) {
        console.error("Error:", error);
    }
}

fetchData();