ノードで async を使用して同時実行性を制御する方法

php中世界最好的语言
リリース: 2018-05-23 11:43:39
オリジナル
1506 人が閲覧しました

今回は、ノードで async を使用して同時実行を制御する方法と、ノードで async を使用して同時実行を制御する場合の注意事項について説明します。以下は実際的なケースです。

目標

lesson5 プロジェクトを作成し、そこにコードを記述します。

コードのエントリ ポイントは app.js です。ノード app.js が呼び出されると、CNode のコミュニティ ホームページ (

https://cnodejs.org) 上のすべてのトピックのタイトル、リンク、最初のコメントが出力されます。 /)。

注: 前のレッスンとは異なり、同時接続の数は 5 に制御する必要があります。

出力例:

[
 {
  "title": "【公告】发招聘帖的同学留意一下这里",
  "href": "http://cnodejs.org/topic/541ed2d05e28155f24676a12",
  "comment1": "呵呵呵呵"
 },
 {
  "title": "发布一款 Sublime Text 下的 JavaScript 语法高亮插件",
  "href": "http://cnodejs.org/topic/54207e2efffeb6de3d61f68f",
  "comment1": "沙发!"
 }
]
ログイン後にコピー

知識ポイント

async の使用方法を学びます (https://github.com/caolan/async)。詳細な非同期デモは次のとおりです: https://github.com/alotang/async_demo

async を使用して同時接続数を制御する方法を学びます。

コースの内容

lesson4 のコードは実際には完璧ではありません。このように言う理由は、レッスン 4 で一度に 40 件のリクエストを送信したためです。CNode を除く他の Web サイトでは、送信する同時接続数が多すぎるため、悪意のあるリクエストとして扱われ、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) 今回は Web サイトのクロールについては説明しません。同時接続数の制御という知識ポイントに焦点を当てましょう。

ところで、別の質問は、いつeventproxyを使用し、いつasyncを使用するかということです。これらはすべて非同期のプロセス制御

に使用されているのではありませんか?

私の答えは次のとおりです:

複数のソース (通常は 10 未満) にアクセスする必要がある場合 場合データを要約する場合は、eventproxy を使用すると便利です。キューを使用する必要がある場合、同時実行数を制御する必要がある場合、または関数型プログラミングの考え方が必要な場合は、async を使用します。ほとんどのシナリオは前者であるため、私は個人的にはほとんどの場合、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 中国語 Web サイトの他の関連記事に注目してください。

推奨読書: 🎜🎜🎜ノードでコールバック関数をpromiseに置き換える方法🎜🎜🎜🎜🎜Vue+better-scrollを使用してアルファベット順のインデックスナビゲーションを実装する方法🎜🎜🎜

以上がノードで async を使用して同時実行性を制御する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!