DEV Community

Mitchell
Mitchell

Posted on

Promise static methods - JavaScript challenges

You can find all the code in this post at the repo Github.


Async programming Promise static methods related challenges


Promise.all()

/**
 * @param {Array} iterable
 * @return {Promise<Array>}
 */

// Async await
function promiseAll(iterable) {
  return new Promise((resolve, reject) => {
    let len = iterable.length;
    let resolved = 0;
    const results = Array.from({ length: len });

    if (len === 0) {
      resolve(results);
      return;
    }

    iterable.forEach(async (item, index) => {
      try {
        const result = await item;
        results[index] = result;
        resolved += 1;

        if (resolved === len) {
          resolve(results);
          return;
        }
      } catch (err) {
        reject(err);
      }
    });
  });
}

// Promise chaining
function promiseAll(iterable) {
  return new Promise((resolve, reject) => {
    const results = [];
    let resolved = 0;

    if (!iterable.length) {
      resolve(results);
      return;
    }

    iterable.forEach((item, index) => {
      Promise.resolve(item)
        .then((data) => {
          results[index] = data;
          resolved += 1;

          if (resolved === iterable.length) {
            resolve(results);
          }
        })
        .catch((err) => {
          reject(err);
        });
    });
  });
}

// Usage example
const p0 = Promise.resolve(3);
const p1 = 42;
const p2 = new Promise((resolve) => {
  setTimeout(() => {
    resolve("foo");
  }, 100);
});

promiseAll([p0, p1, p2]).then((data) => {
  console.log(data); // => [3, 42, 'foo']
});
Enter fullscreen mode Exit fullscreen mode

Promise.allSettled()

/**
 * @param {Array} iterable 
 * @return {Promise<Array<{status: 'fulfilled', value: *} | {status: 'rejected', reason: *}>>}
 */

function promiseAllSettled(iterable) {
  return new Promise((resolve) => {
    const len = iterable.length;
    const results = Array.from({ length: len });
    let pending = len;

    if (!pending) {
      resolve(results);
      return;
    }

    iterable.forEach(async (item, index) => {
      try {
        const value = await item;
        results[index] = {
          status: 'fulfilled',
          value,
        };
      } catch (err) {
        results[index] = {
          status: 'rejected',
          reason: err,
        };
      }

      pending -= 1;
      if (pending === 0) {
        resolve(results);
      }
    });
  });
}

// Usage example
const p0 = Promise.resolve(3);
const p1 = 42;
const p2 = new Promise((_, reject) => {
  setTimeout(() => {
    reject('foo');
  }, 100);
});

promiseAllSettled([p0, p1, p2])
  .then((data) => {
    console.log(data); 
  });
// [
//   { status: 'fulfilled', value: 3 },
//   { status: 'fulfilled', value: 42 },
//   { status: 'rejected', reason: 'foo' },
// ];
Enter fullscreen mode Exit fullscreen mode

Promise.any()

/**
 * @param {Array} iterable
 * @return {Promise}
 */

function promiseAny(iterable) {
  return new Promise((resolve, reject) => {
    const len = iterable.length;

    if (!len) {
      resolve(new AggregateError([]));
    }

    let pending = len;
    const errors = Array.from({ length: len });

    iterable.forEach(async (item, index) => {
      try {
        const value = await item;
        resolve(value);
      } catch (err) {
        errors[index] = err;
        pending -= 1;

        if (!pending) {
          reject(new AggregateError(errors));
        }
      }
    });
  });
}

// Usage example
const p0 = new Promise((resolve) => {
  setTimeout(() => {
    resolve(42);
  }, 100);
});
const p1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject('Err!');
  }, 400);
});

promiseAny([p0, p1])
  .then((data) => {
    console.log(data); // => 42
  });
Enter fullscreen mode Exit fullscreen mode

Promise.race()

/**
 * @param {Array} iterable
 * @return {Promise}
 */

function promiseRace(iterable) {
  return new Promise((resolve, reject) => {
    if (!iterable.length) {
      return;
    }

    iterable.forEach(async (item) => {
      try {
        const result = await item;
        resolve(result);
      } catch (err) {
        reject(err);
      }
    });
  });
}

// Usage example
const p0 = new Promise((resolve) => {
  setTimeout(() => {
    resolve(42);
  }, 100);
});
const p1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject("Err!");
  }, 400);
});

promiseRace([p0, p1]).then((data) => {
  console.log(data); // => 42
});
Enter fullscreen mode Exit fullscreen mode

Promise.reject()

/**
 * @param {*} reason
 * @returns Promise
 */

function promiseReject(reason) {
  return new Promise((_, reject) => {
    reject(reason);
  });
}

// Usage example
const promise = promiseReject('err');
promise.catch((err) => {
  console.log(`Error: ${err}`); // => Error: err
});
Enter fullscreen mode Exit fullscreen mode

Promise.resolve()

/**
 * @param {*} value
 * @return Promise
 */

function promiseResolve(value) {
  // Promise
  if (value instanceof Promise) {
    return value;
  }

  // Thenable
  if (typeof value.then === 'function') {
    return new Promise(value.then.bind(value));
  }

  return new Promise((resolve) => resolve(value));
}

// Usage example
const resolvedThenable = promiseResolve({
  then(resolve, reject) {
    resolve(1);
  }
})

const promise = resolvedThenable;
promise.then((data) => {
  console.log(data); // => 1
});
Enter fullscreen mode Exit fullscreen mode

Promise.withResolvers()

/**
 * @param {*} value
 * @return Promise
 */

function promiseResolve(value) {
  // Promise
  if (value instanceof Promise) {
    return value;
  }

  // Thenable
  if (typeof value.then === 'function') {
    return new Promise(value.then.bind(value));
  }

  return new Promise((resolve) => resolve(value));
}

// Usage example
const resolvedThenable = promiseResolve({
  then(resolve, reject) {
    resolve(1);
  }
})

const promise = resolvedThenable;
promise.then((data) => {
  console.log(data); // => 1
});
Enter fullscreen mode Exit fullscreen mode

Reference

AWS GenAI LIVE image

Real challenges. Real solutions. Real talk.

From technical discussions to philosophical debates, AWS and AWS Partners examine the impact and evolution of gen AI.

Learn more

Top comments (0)

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more