이번에는 노드에서 비동기를 사용하여 동시성을 제어하는 방법과 노드에서 비동기를 사용하여 동시성을 제어할 때 어떤 주의사항이 있는지 보여드리겠습니다. 다음은 실제 사례입니다.
Goal
Lesson5 프로젝트를 만들고 코드를 작성해 보세요.
코드 진입점은 app.js입니다. node app.js가 호출되면 CNode 커뮤니티 홈페이지(https://cnodejs.org)에 모든 주제의 제목, 링크 및 첫 번째 댓글이 출력됩니다. /).json 형식입니다.
참고: 이전 강의와 달리 동시 연결 수를 5개로 제어해야 합니다.
출력 예:
[ { "title": "【公告】发招聘帖的同学留意一下这里", "href": "http://cnodejs.org/topic/541ed2d05e28155f24676a12", "comment1": "呵呵呵呵" }, { "title": "发布一款 Sublime Text 下的 JavaScript 语法高亮插件", "href": "http://cnodejs.org/topic/54207e2efffeb6de3d61f68f", "comment1": "沙发!" } ]
Knowledge points
async 사용법을 알아보세요(https://github.com/caolan/async). 다음은 자세한 비동기 데모입니다: https://github.com/ alsotang/async_demo
비동기를 사용하여 동시 연결 수를 제어하는 방법을 알아보세요.
강의 내용
lesson4의 코드는 실제로 완벽하지 않습니다. 이렇게 말하는 이유는 4강에서 한 번에 40개의 동시 요청을 보냈기 때문입니다. CNode를 제외한 다른 웹사이트에서는 동시 연결을 너무 많이 보내 IP를 차단하면 악의적인 요청으로 간주될 수 있다는 점을 알아야 합니다. .
크롤러를 작성할 때 크롤링할 링크가 1,000개라면 동시에 1,000개의 링크를 보내는 것은 불가능하겠지요? 동시성 수(예: 10개 동시성)를 제어한 다음 천천히 이 1,000개 링크를 캡처해야 합니다.
이 작업은 비동기식으로 수행하기 쉽습니다.
이번에는 async의 mapLimit(arr, Limit, iterator, callback)
인터페이스를 소개하겠습니다. 또한 동시 연결 수를 제어하기 위해 일반적으로 사용되는 또 다른 인터페이스가 있습니다: queue(worker, concurrency).
https://github.com/caolan/async#queueworker-concurrency로 이동할 수 있습니다. 지침을 위해. mapLimit(arr, limit, iterator, callback)
接口。另外,还有个常用的控制并发连接数的接口是 queue(worker, concurrency),
大家可以去 https://github.com/caolan/async#queueworker-concurrency 看看说明。
这回我就不带大家爬网站了,我们来专注知识点:并发连接数控制。
对了,还有个问题是,什么时候用 eventproxy,什么时候使用 async 呢?它们不都是用来做异步流程控制的吗?
我的答案是:
当你需要去多个源(一般是小于 10 个)汇总数据的时候,用 eventproxy 方便;当你需要用到队列,需要控制并发数,或者你喜欢函数式编程思维时,使用 async。大部分场景是前者,所以我个人大部分时间是用 eventproxy 的。
正题开始。
首先,我们伪造一个 fetchUrl(url, callback)
에 사용되지 않나요?
내 대답은:
여러 소스(보통 10개 미만)로 이동해야 할 때 데이터를 요약하려면 대기열을 사용해야 하거나 동시성 수를 제어해야 하거나 함수형 프로그래밍 사고를 좋아할 때 비동기를 사용하는 것이 편리합니다. 대부분의 시나리오는 전자이므로 개인적으로 대부분의 경우 eventproxy를 사용합니다.
시작해 보세요.
먼저 fetchUrl(url, callback)
함수를 위조합니다. 이 함수의 기능은
fetchUrl('http://www.baidu.com', function (err, content) { // do something with `content` });를 통해 호출하면 http://www.baidu.com을 반환한다는 것입니다. 페이지 내용이 다시 나타납니다. 물론 여기 반품 내용은 허위이고 반품 지연은 랜덤입니다. 그리고 호출되면 동시에 호출되는 곳이 몇 군데인지 알려줍니다.
// 并发连接数的计数器 var concurrencyCount = 0; var fetchUrl = function (url, callback) { // delay 的值在 2000 以内,是个随机的整数 var delay = parseInt((Math.random() * 10000000) % 2000, 10); concurrencyCount++; console.log('现在的并发数是', concurrencyCount, ',正在抓取的是', url, ',耗时' + delay + '毫秒'); setTimeout(function () { concurrencyCount--; callback(null, url + ' html content'); }, delay); };그런 다음 링크 세트를 위조합니다
var urls = []; for(var i = 0; i < 30; i++) { urls.push('http://datasource_' + i); }
이 링크 세트는 다음과 같습니다.
그런 다음 async.mapLimit를 사용하여 동시에 크롤링하고 결과를 얻습니다.async.mapLimit(urls, 5, function (url, callback) { fetchUrl(url, callback); }, function (err, result) { console.log('final:'); console.log(result); });실행 출력은 다음과 같습니다.
처음에는 동시 링크 수가 1개부터 증가하기 시작하고, 5개로 증가하면 더 이상 증가하지 않는 것을 볼 수 있습니다. 작업 중 하나가 완료되면 가져오기를 계속합니다. 동시 연결 수는 항상 5개로 제한됩니다.
이 기사의 사례를 읽은 후 방법을 마스터했다고 생각합니다. 더 흥미로운 정보를 보려면 PHP 중국어 웹사이트의 다른 관련 기사를 주목하세요!
위 내용은 동시성을 제어하기 위해 노드에서 비동기를 사용하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!