Given a list of promises and their priorities, call them parallelly and resolve with the value of the first promise with the most priority. If all the promises fail then reject with a custom error.
Example
const promises = [ {status: 'resolve', priority: 4}, {status: 'reject', priority: 1}, {status: 'resolve', priority: 2}, {status: 'reject', priority: 3} ]; resolvePromisesWithPriority(promises); // {status: 'resolve', priority: 2}
To solve this, in the resolvePromisesWithPriority
function we will create a new promise and return it.
Sort the input promises in ascending order of priority and then execute all of these in parallel.
While executing, use a variable to track the most priority promise, if any promise rejects and it is the promise of most priority, update the variable to the next in priority.
In the end, if any promise resolves and it is of most priority, resolve it, else if all the promises fail then reject with the custom error.
To track if all the promises are finished, we will use another variable named taskCompleted
.
function resolvePromisesWithPriority(promises){ // sort the promises based on priority promises.sort((a, b) => a.priority - b.priority); // track the rejected promise let rejected = {}; // track the result let result = {}; // track the position of the most priority let mostPriority = 0; // track the no of promises executed let taskCompleted = 0; // return a new promise return new Promise((resolve, reject) => { // run each task in parallel promises.forEach(({task, priority}, i) => { // if the task is done // store it in the result task.then((value) => { result[priority] = value; mostPriority = Math.min(mostPriority, i); }).catch((error) => { // if the promise is rejected // track the rejected promises just for reference rejected[priority] = true; // if the rejected task is the least priority one // move to the next least priority if(priority === promises[mostPriority].priority){ mostPriority++; } }).finally(() => { // if the value priority is not reject // and is the least priority //resolve with these value if(!rejected[priority] && priority === promises[mostPriority].priority){ console.log(rejected); resolve(priority); } // track the no of tasks completed taskCompleted++; // if all the tasks are finished and none of them have been resolved // reject with custom error if(taskCompleted === promises.length){ reject("All Apis Failed"); } }); }); }); };
Input: // create a promise that rejects or resolves // randomly after some time function createAsyncTask() { const value = Math.floor(Math.random() * 10); return new Promise((resolve, reject) => { setTimeout(() => { if(value < 7){ reject(); }else{ resolve(value); } }, value * 100); }); }; const promises = [ {task: createAsyncTask(), priority: 1}, {task: createAsyncTask(), priority: 4}, {task: createAsyncTask(), priority: 3}, {task: createAsyncTask(), priority: 2} ]; resolvePromisesWithPriority(promises).then((result)=>{ console.log(result); }, (error) => { console.log(error); }); Output: /* // rejected promise as per their priority { "1": true, "3": true, "4": true } // resolve promise as per their priority 2 */
Note:- As the tasks are time bounded, the promise that resolves first, gets printed.