我正在写一个爬虫。任务是在最坏的情况下扫描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一般如何工作,我已经使用了很多次,但是这个用例对我来说是新的。有人可以帮忙吗?
答案 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()
和半递归功能,就可以实现 ,但是它的可读性要差得多在我看来,比起带有清晰循环的简单异步功能。