Node.js 4:《使用 eventproxy 控制并發(fā)》

2018-08-07 15:22 更新

目標(biāo)

建立一個(gè) lesson4 項(xiàng)目,在其中編寫(xiě)代碼。

代碼的入口是 app.js,當(dāng)調(diào)用 node app.js 時(shí),它會(huì)輸出 CNode(https://cnodejs.org/ ) 社區(qū)首頁(yè)的所有主題的標(biāo)題,鏈接和第一條評(píng)論,以 json 的格式。

輸出示例:

[
  {
    "title": "【公告】發(fā)招聘帖的同學(xué)留意一下這里",
    "href": "http://cnodejs.org/topic/541ed2d05e28155f24676a12",
    "comment1": "呵呵呵呵"
  },
  {
    "title": "發(fā)布一款 Sublime Text 下的 JavaScript 語(yǔ)法高亮插件",
    "href": "http://cnodejs.org/topic/54207e2efffeb6de3d61f68f",
    "comment1": "沙發(fā)!"
  }
]

挑戰(zhàn)

以上文目標(biāo)為基礎(chǔ),輸出 comment1 的作者,以及他在 cnode 社區(qū)的積分值。

示例:

[
  {
    "title": "【公告】發(fā)招聘帖的同學(xué)留意一下這里",
    "href": "http://cnodejs.org/topic/541ed2d05e28155f24676a12",
    "comment1": "呵呵呵呵",
    "author1": "auser",
    "score1": 80
  },
  ...
]

知識(shí)點(diǎn)

  1. 體會(huì) Node.js 的 callback hell 之美
  2. 學(xué)習(xí)使用 eventproxy 這一利器控制并發(fā)

課程內(nèi)容

這一章我們來(lái)到了 Node.js 最牛逼的地方——異步并發(fā)的內(nèi)容了。

上一課我們介紹了如何使用 superagent 和 cheerio 來(lái)取主頁(yè)內(nèi)容,那只需要發(fā)起一次 http get 請(qǐng)求就能辦到。但這次,我們需要取出每個(gè)主題的第一條評(píng)論,這就要求我們對(duì)每個(gè)主題的鏈接發(fā)起請(qǐng)求,并用 cheerio 去取出其中的第一條評(píng)論。

CNode 目前每一頁(yè)有 40 個(gè)主題,于是我們就需要發(fā)起 1 + 40 個(gè)請(qǐng)求,來(lái)達(dá)到我們這一課的目標(biāo)。

后者的 40 個(gè)請(qǐng)求,我們并發(fā)地發(fā)起:),而且不會(huì)遇到多線程啊鎖什么的,Node.js 的并發(fā)模型跟多線程不同,拋卻那些觀念。更具體一點(diǎn)的話,比如異步到底為何異步,Node.js 為何單線程卻能并發(fā)這類(lèi)走近科學(xué)的問(wèn)題,我就不打算講了。對(duì)于這方面有興趣的同學(xué),強(qiáng)烈推薦 @樸靈 的 《九淺一深Node.js》: http://book.douban.com/subject/25768396/ 。

有些逼格比較高的朋友可能聽(tīng)說(shuō)過(guò) promise 和 generator 這類(lèi)概念。不過(guò)我呢,只會(huì)講 callback,主要原因是我個(gè)人只喜歡 callback。

這次課程我們需要用到三個(gè)庫(kù):superagent cheerio eventproxy(https://github.com/JacksonTian/eventproxy )

手腳架的工作各位自己來(lái),我們一步一步來(lái)一起寫(xiě)出這個(gè)程序。

首先 app.js 應(yīng)該長(zhǎng)這樣

var eventproxy = require('eventproxy');
var superagent = require('superagent');
var cheerio = require('cheerio');
// url 模塊是 Node.js 標(biāo)準(zhǔn)庫(kù)里面的
// http://nodejs.org/api/url.html
var url = require('url');

var cnodeUrl = 'https://cnodejs.org/';

superagent.get(cnodeUrl)
  .end(function (err, res) {
    if (err) {
      return console.error(err);
    }
    var topicUrls = [];
    var $ = cheerio.load(res.text);
    // 獲取首頁(yè)所有的鏈接
    $('#topic_list .topic_title').each(function (idx, element) {
      var $element = $(element);
      // $element.attr('href') 本來(lái)的樣子是 /topic/542acd7d5d28233425538b04
      // 我們用 url.resolve 來(lái)自動(dòng)推斷出完整 url,變成
      // https://cnodejs.org/topic/542acd7d5d28233425538b04 的形式
      // 具體請(qǐng)看 http://nodejs.org/api/url.html#url_url_resolve_from_to 的示例
      var href = url.resolve(cnodeUrl, $element.attr('href'));
      topicUrls.push(href);
    });

    console.log(topicUrls);
  });

運(yùn)行 node app.js

輸出如下圖:

以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)