| 7 | 7 | * @param {Function} fn |
| 8 | 8 | * @returns {Function} |
| 9 | 9 | */ |
| 10 | | export const promisify = () => { |
| 11 | | throw new Error('Remove this line and implement the function'); |
| 10 | export const promisify = (fn) => { |
| 11 | // Edge Case: Handle when fn is not a function |
| 12 | if (typeof fn !== 'function') { |
| 13 | throw new TypeError('Expected a function'); |
| 14 | } |
| 15 | |
| 16 | return function (...args) { |
| 17 | return new Promise((resolve, reject) => { |
| 18 | // Edge Case: Handle errors thrown by the original function |
| 19 | try { |
| 20 | fn.call(this, ...args, (error, data) => { |
| 21 | if (error) { |
| 22 | reject(error); |
| 23 | } else { |
| 24 | resolve(data); |
| 25 | } |
| 26 | }); |
| 27 | } catch (error) { |
| 28 | reject(error); |
| 29 | } |
| 30 | }); |
| 31 | }; |
| 32 | // Handled Edge Cases: fn is not a function, errors thrown by the original function |
| 12 | 33 | }; |
| 13 | 34 | |
| 14 | 35 | /** |
| 15 | 36 | * @param {Promise[]} promises |
| 16 | 37 | * @returns {Promise} |
| 17 | 38 | */ |
| 18 | | export const all = () => { |
| 19 | | throw new Error('Remove this line and implement the function'); |
| 39 | export const all = (promises) => { |
| 40 | // Edge Case: Handle when promises is not an array |
| 41 | if (!Array.isArray(promises)) { |
| 42 | return Promise.reject(new TypeError('Expected an array of promises')); |
| 43 | } |
| 44 | |
| 45 | // Edge Case: Handle empty array |
| 46 | if (promises.length === 0) { |
| 47 | return Promise.resolve([]); |
| 48 | } |
| 49 | |
| 50 | return new Promise((resolve, reject) => { |
| 51 | const results = new Array(promises.length); |
| 52 | let completed = 0; |
| 53 | |
| 54 | promises.forEach((promise, index) => { |
| 55 | // Edge Case: Handle non-promise values by converting them to resolved promises |
| 56 | Promise.resolve(promise) |
| 57 | .then((value) => { |
| 58 | results[index] = value; |
| 59 | completed++; |
| 60 | |
| 61 | // Edge Case: Resolve only when all promises have completed |
| 62 | if (completed === promises.length) { |
| 63 | resolve(results); |
| 64 | } |
| 65 | }) |
| 66 | .catch((error) => { |
| 67 | // Edge Case: Reject immediately when any promise rejects |
| 68 | reject(error); |
| 69 | }); |
| 70 | }); |
| 71 | }); |
| 72 | // Handled Edge Cases: promises is not an array, empty array, non-promise values, immediate rejection |
| 20 | 73 | }; |
| 21 | 74 | |
| 22 | 75 | /** |
| 23 | 76 | * @param {Promise[]} promises |
| 24 | 77 | * @returns {Promise} |
| 25 | 78 | */ |
| 26 | | export const allSettled = () => { |
| 27 | | throw new Error('Remove this line and implement the function'); |
| 79 | export const allSettled = (promises) => { |
| 80 | // Edge Case: Handle when promises is not an array |
| 81 | if (!Array.isArray(promises)) { |
| 82 | return Promise.reject(new TypeError('Expected an array of promises')); |
| 83 | } |
| 84 | |
| 85 | // Edge Case: Handle empty array |
| 86 | if (promises.length === 0) { |
| 87 | return Promise.resolve([]); |
| 88 | } |
| 89 | |
| 90 | return new Promise((resolve) => { |
| 91 | const results = new Array(promises.length); |
| 92 | let completed = 0; |
| 93 | |
| 94 | promises.forEach((promise, index) => { |
| 95 | // Edge Case: Handle non-promise values by converting them to resolved promises |
| 96 | Promise.resolve(promise) |
| 97 | .then((value) => { |
| 98 | results[index] = { status: 'fulfilled', value }; |
| 99 | completed++; |
| 100 | |
| 101 | // Edge Case: Resolve only when all promises have settled |
| 102 | if (completed === promises.length) { |
| 103 | resolve(results); |
| 104 | } |
| 105 | }) |
| 106 | .catch((reason) => { |
| 107 | results[index] = { status: 'rejected', reason }; |
| 108 | completed++; |
| 109 | |
| 110 | // Edge Case: Resolve only when all promises have settled |
| 111 | if (completed === promises.length) { |
| 112 | resolve(results); |
| 113 | } |
| 114 | }); |
| 115 | }); |
| 116 | }); |
| 117 | // Handled Edge Cases: promises is not an array, empty array, non-promise values |
| 28 | 118 | }; |
| 29 | 119 | |
| 30 | 120 | /** |
| 31 | 121 | * @param {Promise[]} promises |
| 32 | 122 | * @returns {Promise} |
| 33 | 123 | */ |
| 34 | | export const race = () => { |
| 35 | | throw new Error('Remove this line and implement the function'); |
| 124 | export const race = (promises) => { |
| 125 | // Edge Case: Handle when promises is not an array |
| 126 | if (!Array.isArray(promises)) { |
| 127 | return Promise.reject(new TypeError('Expected an array of promises')); |
| 128 | } |
| 129 | |
| 130 | // Edge Case: Handle empty array |
| 131 | if (promises.length === 0) { |
| 132 | return new Promise(() => {}); // Never settles |
| 133 | } |
| 134 | |
| 135 | return new Promise((resolve, reject) => { |
| 136 | promises.forEach((promise) => { |
| 137 | // Edge Case: Handle non-promise values by converting them to resolved promises |
| 138 | Promise.resolve(promise) |
| 139 | .then((value) => { |
| 140 | // Edge Case: Resolve with the first settled promise's value |
| 141 | resolve(value); |
| 142 | }) |
| 143 | .catch((error) => { |
| 144 | // Edge Case: Reject with the first settled promise's error |
| 145 | reject(error); |
| 146 | }); |
| 147 | }); |
| 148 | }); |
| 149 | // Handled Edge Cases: promises is not an array, empty array, non-promise values, first settled promise behavior |
| 36 | 150 | }; |
| 37 | 151 | |
| 38 | 152 | /** |
| 39 | 153 | * @param {Promise[]} promises |
| 40 | 154 | * @returns {Promise} |
| 41 | 155 | */ |
| 42 | | export const any = () => { |
| 43 | | throw new Error('Remove this line and implement the function'); |
| 156 | export const any = (promises) => { |
| 157 | // Edge Case: Handle when promises is not an array |
| 158 | if (!Array.isArray(promises)) { |
| 159 | return Promise.reject(new TypeError('Expected an array of promises')); |
| 160 | } |
| 161 | |
| 162 | // Edge Case: Handle empty array |
| 163 | if (promises.length === 0) { |
| 164 | return Promise.reject(new AggregateError([], 'All promises were rejected')); |
| 165 | } |
| 166 | |
| 167 | return new Promise((resolve, reject) => { |
| 168 | const errors = new Array(promises.length); |
| 169 | let rejectedCount = 0; |
| 170 | |
| 171 | promises.forEach((promise, index) => { |
| 172 | // Edge Case: Handle non-promise values by converting them to resolved promises |
| 173 | Promise.resolve(promise) |
| 174 | .then((value) => { |
| 175 | // Edge Case: Resolve immediately when any promise resolves |
| 176 | resolve(value); |
| 177 | }) |
| 178 | .catch((error) => { |
| 179 | errors[index] = error; |
| 180 | rejectedCount++; |
| 181 | |
| 182 | // Edge Case: Reject only when all promises have rejected |
| 183 | if (rejectedCount === promises.length) { |
| 184 | reject(new AggregateError(errors, 'All promises were rejected')); |
| 185 | } |
| 186 | }); |
| 187 | }); |
| 188 | }); |
| 189 | // Handled Edge Cases: promises is not an array, empty array, non-promise values, all promises rejected |
| 44 | 190 | }; |