我正在写一个爬虫。任务是在最坏的情况下扫描 10 页。我可能碰巧只需要扫描一页,但这取决于页面内容。如果第一页上没有我要查找的项目,那么我们将转到第二页,直到达到第 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)
}
所以我不知道如何使用 Native Promises 和 Typescript 来实现它。我知道 Promises 通常是如何工作的,并且我多次使用它们,但这个用例对我来说是新的。谁能帮忙?
最佳答案
您需要两个函数(也许三个),一个用于请求页面(我们将其命名为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()
和半递归函数,但在我看来,它的可读性远不如带有清晰循环的简单异步函数。
关于javascript - 在循环中创建 Promise 并在某些已解决的条件发生时打破循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53032396/