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']
});
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' },
// ];
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
});
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
});
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
});
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
});
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
});
Reference
- Promise.all() - MDN
- Promise.allSettled() - MDN
- Promise.any() - MDN
- Promise.race() - MDN
- Promise.reject() - MDN
- Promise.resolve() - MDN
- Promise.withResolvers() - MDN
- 32. implement
Promise.all()
- BFE.dev - 33. implement
Promise.allSettled()
- BFE.dev - 34. implement
Promise.any()
- BFE.dev - 2721. Execute Asynchronous Functions in Parallel - LeetCode
- GreatFrontEnd