我的目标是用 Dart 创建一种网络爬虫。为此,我想维护一个任务队列,其中存储需要爬网的元素(例如 URL)。这些元素在爬行函数中爬行,该函数返回需要处理的更多元素的列表。因此,这些元素被添加到队列中。示例代码:
import "dart:collection";
final queue = Queue<String>();
main() async{
queue
..add("...")
..add("...")
..add("...");
while (queue.isNotEmpty) {
results = await crawl(queue.removeFirst());
queue.addAll(results);
}
}
Future<List<String>> crawl(String x) async {
...
res = await http.get(x)
...
return results;
}
Run Code Online (Sandbox Code Playgroud)
这段粗略代码一次仅处理一个元素。不过,我想要一个工作池(例如 5 个),它们从队列中取出元素并同时处理它们,然后将结果添加回队列。由于瓶颈是 HTTP 请求,我认为对多个工作线程进行 Future.wait() 调用可以加快执行速度。但是我不想让服务器超载,因此我也想限制工作人员的数量。
这可以用基本的异步原语和信号量来实现吗?我希望尽可能避免隔离,以使解决方案尽可能简单。