동시성을 제어하기 위해 노드에서 비동기를 사용하는 방법

php中世界最好的语言
풀어 주다: 2018-05-23 11:43:39
원래의
1519명이 탐색했습니다.

이번에는 노드에서 비동기를 사용하여 동시성을 제어하는 ​​방법과 노드에서 비동기를 사용하여 동시성을 제어할 때 어떤 주의사항이 있는지 보여드리겠습니다. 다음은 실제 사례입니다.

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)

이번에는 웹사이트 크롤링에 대해 설명하지 않겠습니다. 지식 포인트인 동시 연결 수 제어에 집중하겠습니다.

그런데 또 다른 질문은 언제 eventproxy를 사용하고 언제 async를 사용해야 하느냐는 것입니다. 모두 비동기 프로세스 제어

에 사용되지 않나요?

내 대답은:

여러 소스(보통 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 중국어 웹사이트의 다른 관련 기사를 주목하세요!

🎜추천 자료: 🎜🎜🎜노드에서 콜백 함수를 프라미스로 바꾸는 방법🎜🎜🎜🎜🎜Vue+better-scroll을 사용하여 알파벳순 인덱스 탐색을 구현하는 방법🎜🎜🎜

위 내용은 동시성을 제어하기 위해 노드에서 비동기를 사용하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
최신 이슈
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿