Is my use of Promises in an asynchronous function correct?

Viewed 190

I'm finally trying to get to grips with Promises, one of the newer and more mysterious corners of JavaScript. The following is a problem I came across in a technical test, and which seems to get to the heart of what I don't understand about Promises.

The problem is as follows:

  • You have a predefined class called Service, with the following methods:
    • generate() - which generates a random number between 0 and 100.
    • guess(yourGuess) - which takes a given guess for the random number, and returns a Promise. This Promise, in turn will do one of two things within 100 ms:
      • If the guess is correct, the Promise will be resolved, with the guess corresponding to that Promise as its first argument.
      • If the guess is incorrect, the Promise will be rejected.
    • submit(yourGuess) - which submits a guess you believe is correct.
  • You have to write an asynchronous function, main(), which will:
    • Generate a random number using a Service object.
    • Submit a correct guess to the same object within 400 ms.
    • Any rejected Promises have to be caught.

This is my code:

const MAX_NUMBER = 100;

async function main()
{
    const service = new Service();
    let guessInPromise;

    service.generate();

    for(let i = 0; i <= MAX_NUMBER; i++)
    {
        service.guess(i)
            .then(guessInPromise => service.submit(guessInPromise));
            .catch(err => console.log(err));
    }

    return service;
}

Would my code get the job done? Is there anything I've obviously misunderstood about Promises and asynchronous functions?

1 Answers

Given your requirements, I'd assume the task is to somehow guess the correct answer in 400ms whereas each guess takes 100ms. A very simple solution here would be to do all guesses in parallel and only wait for the first to be resolved.

This would work because Service.guess is described to only resolve it's returned promise for valid guesses (others will be rejected).

Very helpful here would be: Promise.any

And an example could be:

// very simple mock implementation for the described Service class
class Service
{
  value = null;

  generate() {
    this.value = Math.floor(Math.random() * 101);
  }

  guess(yourGuess) {
    return new Promise(((resolve, reject) => {
      setTimeout(() => {
          yourGuess === this.value ? resolve(yourGuess) : reject()
      }, 100);
    }));
  }

  submit(yourGuess) {
    return yourGuess === this.value;
  }
}

const MAX_NUMBER = 100;

(async function main() {
  const service = new Service();

  service.generate();

  try {
    // await first resolved guess
    const assumedCorrect = await Promise.any(
      // map 0 ... 100 to service.guess(...)
      Array.from({length: MAX_NUMBER + 1}).map((_, i) => service.guess(i))
    );

    console.log(
      assumedCorrect,
      service.submit(assumedCorrect)
    );
  }
  catch {
    console.log('No guess was correct... :(');
  }
})();

Related