在循环中创建Promises,并在某些解决的情况发生时中断循环

时间:2018-10-28 14:09:54

标签: javascript typescript promise

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

所以我不知道如何使用本机Promise和Typescript来实现它。我知道Promises一般如何工作,我已经使用了很多次,但是这个用例对我来说是新的。有人可以帮忙吗?

1 个答案:

答案 0 :(得分: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;
}

请注意,这与同步代码有多相似。有趣的是在async关键字之前添加的function和在await返回的Promise之前添加的requestPage(page)

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


值得注意的是,无需使用异步功能,巧妙地使用链接.then()和半递归功能,就可以实现 ,但是它的可读性要差得多在我看来,比起带有清晰循环的简单异步功能。