【问题标题】:Creating Promises in loop and break the loop as some resolved condition occur在循环中创建 Promise 并在某些已解决的条件发生时中断循环
【发布时间】:2018-10-28 14:09:54
【问题描述】:

我正在写一个爬虫。任务是在最坏的情况下扫描 10 页。我可能只需要扫描 1 页,但这取决于页面内容。如果第一页上没有我要查找的项目,那么我们将移至第二页,直到达到 10 页。我们对第 11 页及更多内容不感兴趣。所以我们有一个限制。我想调用第 1 页的请求,如果找到项目,则中断 for 循环并解析 Promise。

伪代码:

func findItem(item: Item): Promise<PageIndex> {
    for (let page=1; page<=10; page++) {
        create url with page as url
        create promise that request url and resolve to content as content
        if content contains item {
            return Promise.resolve(page); // We are interesting in on which page the item is.
            // Here we are breaking loop and exit function because we
            // Found what we were looking for
        }
        // continue to next page because content does not contain item on this page
    }
    // We didnt find item on first 10 pages
    return Promise.resolve(-1)
}

所以我不知道如何使用 Native Promises 和 Typescript 来实现这一点。我知道 Promises 一般是如何工作的,并且我多次使用它们,但这个用例对我来说是新的。有人可以帮忙吗?

【问题讨论】:

  • 使用递归或async/await 语法

标签: javascript typescript promise


【解决方案1】:

您需要两个函数(可能三个),一个用于请求页面(让我们恰当地将其命名为 requestPage(),我不会展示您应该如何实现它,因为它应该相当明显)并返回解析结果(即可能是另一个函数,具体取决于您的解析需求)和编排器(您在伪代码中的循环)。

这里的技巧是你的编排器应该是一个async 函数。

async function findItem(item: Item) {
  for (let page = 1; page <= 10; page++) {
    const contents = await requestPage(page);
    if (contents.include('whateverYouAreInterestedIn')) {
      return page;
    }
  }
  return -1;
}

请注意这与同步外观代码的相似程度。有趣的部分是我在function 关键字之前添加的async,以及我在requestPage(page) 返回的Promise 之前添加的await

此外,作为附录,TypeScript 通常可以推断函数(甚至是异步函数)的返回类型,因此几乎不需要明确返回类型。


值得注意的是,可以在不使用异步函数的情况下实现,巧妙地使用链接.then()s 和半递归函数,但在我的意见比具有清晰循环的简单异步函数。

【讨论】:

  • 非常感谢。它与异步等待一起工作。这对我来说是新的,但我读过它并且非常适合。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多