Promises: How to start

Hello all,

I am having trouble starting this problem and would love to hear any suggestions/ reasonings that would help steer me in the right direction. I somewhat understand promises (clearer than callbacks, etc) and how resolve/reject work in the code but I am confused about how to start the code that will give the output in the test examples.
You’re in charge of completing a race simulator. The code contains the following components:

  • getRacer(name) - This method accepts a racer name and returns a racer as a promise, indicating how fast the racer will complete his or if the racer will forfeit during the race. You’ll notice that there is a 30% chance that a racer will forfeit.
  • race(racers) - This method accepts an array of racers and will start the race with the provided racers.
  • start(racers) - This method accepts a list of racers and will print the outcome of the race.
    function start(racers) {
    return new Promise((resolve, reject) => {
    // Your code here.
    });
    }

function getRacer(name) {
if (Math.random() <= 0.30) {
return Promise.reject(name + " forfeits")
}
return new Promise((resolve, reject) => {
setTimeout(() => resolve(name), Math.random() * 5000);
});
}

function race(racers) {
console.log(“starting race…”)
start(racers).then(result => {
console.log("results: " + result)
})
}

// test example(s)

race([getRacer(“anthony”), getRacer(“john”), getRacer(“joe”)])
→ “john finished first, anthony finished second, and joe finished third”

race([getRacer(“anthony”), getRacer(“john”), getRacer(“joe”)])
→ “joe finished first, anthony finished second, and john finished third”

race([getRacer(“anthony”), getRacer(“john”), getRacer(“joe”)])
→ “joe finished first, john finished second, anthony forfeited”
The code you will complete will determine who finished first, second and third as illustrated by the test cases above. Racers who finished the race, should always be listed first, and those who forfeited, last.
Requirements:

  • You CANNOT add/modify anything except where it says “Your code here”
  • Output can be generated with console.log()
  • Output must match the string format from the test cases, though the names of the racers of course, can change depending on what names are used when calling race()

Well I don’t really know how to explain it all to you, not being great with promises myself, but here’s what I came up with after some serious review and a lot of trial and error in order to get something working. Maybe this will help you to understand or come up with something better. Good Luck.

Spoiler
function start(racers) {
    return new Promise((resolve, reject) => {
            const place = ['first, ', 'second, and ', 'third'];
            const position = [];
            const forfeited = [];

            const complete = () => {
                let resStr = '';

                for (let i=0; i < position.length; i++) {
                    resStr += `${position[i]} finished ${place[i]}`;
                }

                switch (forfeited.length) {
                    case 1:
                        resStr += forfeited[0];
                        break;
                    case 2:
                        resStr += `${forfeited[0]}, and ${forfeited[1]}`;
                        break;
                    case 3:
                        resStr = `${forfeited[0]}, ${forfeited[1]}, and ${forfeited[2]}`;
                        break;
                }
                resolve(resStr);
            }

            const thenFunc = (result) => {
                position.push(result);
                if (forfeited.length + position.length == 3) {
                    complete();
                }
            }

            const catchFunc = (result) => {
                forfeited.push(result);
                if (forfeited.length + position.length == 3) {
                    complete();
                }
            }

            racers[0].then(res => thenFunc(res))
                    .catch(res => catchFunc(res));
            racers[1].then(res => thenFunc(res))
                    .catch(res => catchFunc(res));
            racers[2].then(res => thenFunc(res))
                    .catch(res => catchFunc(res));
        
    });
};