【问题标题】:Is my use of Promises in an asynchronous function correct?我在异步函数中使用 Promises 是否正确?
【发布时间】:2021-03-23 22:57:36
【问题描述】:

我终于尝试掌握 Promises,这是 JavaScript 的更新和更神秘的角落之一。以下是我在技术测试中遇到的一个问题,似乎触及了我对 Promises 的不理解的核心。

问题如下:

  • 您有一个名为Service预定义类,具有以下方法:
    • generate() - 生成 0 到 100 之间的随机数。
    • guess(yourGuess) - 对随机数进行给定的猜测,并返回一个 Promise。这个 Promise 又会在 100 毫秒 内做两件事之一:
      • 如果猜测正确,则 Promise 将被解析,与该 Promise 对应的猜测作为其第一个参数。
      • 如果猜测不正确,Promise 将被拒绝。
    • submit(yourGuess) - 提交您认为正确的猜测。
  • 您必须编写一个异步函数main(),它将:
    • 使用Service 对象生成一个随机数。
    • 在 400 毫秒内提交对同一对象的正确猜测。
    • 必须捕获任何被拒绝的 Promise。

这是我的代码:

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;
}

我的代码能完成工作吗?我对 Promise 和异步函数有什么明显误解吗?

【问题讨论】:

  • generate()guess() 是否返回 Promise 对象?
  • const guessInPromise; 没有意义,因为你没有给它一个初始值,以后也不能给它一个值。
  • 我认为这里的诀窍是使用Service.guess(...) 将所有可能的猜测映射到promise,然后等待Promise.any()
  • @crashmstr 实际上,它应该只是错误 - 声明一个没有赋值的 const 是没有意义的,并且是一种禁止的语法。
  • 这段代码可以运行,但是有一些奇怪的地方。为什么返回service?记录“正确的数字是 X”是否有意义。与其使用一大堆浮动的 Promise,不如在猜测正确后返回结果。您的代码当前会立即返回服务对象。编辑:我看到 Yoshi 打败了我。

标签: javascript asynchronous promise


【解决方案1】:

根据您的要求,我假设任务是以某种方式在 400 毫秒内猜出正确答案,而每次猜测需要 100 毫秒。这里一个非常简单的解决方案是并行进行所有猜测,然后只等待第一个被解决。

这会起作用,因为 Service.guess 被描述为仅解决它返回的有效猜测的承诺(其他人将被拒绝)。

这里很有帮助:Promise.any

举个例子:

// 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... :(');
  }
})();

【讨论】:

  • 道歉。我忘记提及的一件事是,该问题指定任何被拒绝的 Promise - guess() 将拒绝如果有问题的猜测不正确 - 必须被捕获。在.any() 之后粘贴.catch() 会起作用吗?
  • 啊好吧,给我一点时间。不过,鉴于Promise.any 的工作原理,只有在没有猜测正确的情况下才会被拒绝。那么应该抓到哪一个呢?
  • 我添加了一个简单的 try/catch 块。尽管您需要减少 MAX_NUMBER 并尝试几次,才能真正触发捕获(在没有做出有效猜测的情况下)。
猜你喜欢
  • 2017-06-11
  • 1970-01-01
  • 2021-01-24
  • 2020-04-01
  • 2021-02-20
  • 1970-01-01
  • 2020-04-11
  • 2016-06-17
  • 1970-01-01
相关资源
最近更新 更多