成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

co-parallel & co-gather源碼解析

caozhijian / 1499人閱讀

摘要:昨天也是好好的看了一下的源碼,今天打算自己來做一下解析。源碼如下這段代碼真的是很短,但是方法真的很巧妙。因?yàn)閮蓚€(gè)方法用到了,這里把的源碼也貼出來源碼的描述就是為了執(zhí)行而創(chuàng)建的。最后再次感謝提供的思路。

原文鏈接,轉(zhuǎn)載請注明出處

最近看了Ma63d關(guān)于爬蟲的這篇文章,正好自己也在做爬蟲,看到他在文中提到了co-parallel和co-gather,就打算改一下自己的代碼(本來代碼就只是為了爬一些自己感興趣的東西,現(xiàn)在還在改,地址在這里)。昨天也是好好的看了一下co-parallel的源碼,今天打算自己來做一下解析。

co-parallel

源碼如下:

var thread = require("co-thread");

module.exports = function *parallel(thunks, n){
  var n = Math.min(n || 5, thunks.length);
  var ret = [];
  var index = 0;

  function *next() {
    var i = index++;
    ret[i] = yield thunks[i];
    if (index < thunks.length) yield next;
  }

  yield thread(next, n);

  return ret;
};

這段代碼真的是很短,但是方法真的很巧妙。因?yàn)閮蓚€(gè)方法用到了co-thread,這里把co-thread的源碼也貼出來:

function thread(fn, n) {
  var gens = [];
  while (n--) gens.push(fn);
  return gens;
}

Run fn n times in parallel.

源碼的描述就是為了parallel執(zhí)行而創(chuàng)建的。由于在next外部創(chuàng)建了一個(gè)index變量,通過控制index的變化就可以使得每次執(zhí)行的next函數(shù)都是不同的函數(shù),在next中繼續(xù)遞歸yield自己的話就是可以繼續(xù)執(zhí)行不同的next,最終把所有的thunks都yield了一遍,方法是不是很巧妙。

如果你覺得我說的話很混亂,那我們還是還是拿一個(gè)co-parallel中的例子來講吧

var request = require("co-request");
var co = require("co");
var parallel = require("co-parallel");

var urls = [
  "http://google.com",
  "http://yahoo.com",
  "http://ign.com",
  "http://cloudup.com",
  "http://myspace.com",
  "http://facebook.com",
  "http://cuteoverload.com",
  "http://uglyoverload.com",
  "http://segment.io"
];

function *status(url) {
  console.log("GET %s", url);
  var s = (yield request(url)).statusCode;
  return s;
}

co(function *(){
  var start = Date.now();
  var reqs = urls.map(status);
  var res = yield parallel(reqs, 3);
  console.log(res);
  console.log("duration: %dms", Date.now() - start);
});

直接看到var reqs = urls.map(status);這句,由于傳遞給map的callback是一個(gè)Generator函數(shù),所以最后的返回就是Generator的內(nèi)部指針,也就是Iterator,也就是status()執(zhí)行了一遍返回的結(jié)果。

再到var res = yield parallel(reqs, 3);這里,由于parallel是一個(gè)Generator,所以直接進(jìn)入parallel中,因?yàn)?b>n=3所以thread返回的數(shù)組內(nèi)容應(yīng)該是類似這個(gè) [function*() {yield thunks[0]},function*(){yield thunks[1]}]。由于yield thread返回的結(jié)果是數(shù)組,在co中會對數(shù)組做Promise.all(obj.map(toPromise, this));因?yàn)閛bj中都是Generator,所以toPromise會直接對每一個(gè)Generator繼續(xù)調(diào)用co(function*(){yield thunk[i]})。在next中最后又繼續(xù)yield自己,所以當(dāng)當(dāng)一個(gè)thunk結(jié)束之后會繼續(xù)下一個(gè)thunk。

co-gather

co-gather實(shí)現(xiàn)的和co-parallel差不多的功能,只是增加了并行錯(cuò)誤處理機(jī)制。因?yàn)?b>Promise.all方法會在其中任何一個(gè)出問題的時(shí)候都把錯(cuò)誤扔出來, co-gather是對all中每一個(gè)方法都做了錯(cuò)誤處理,讓Promise.all方法不會拋錯(cuò),源碼如下:

var thread = require("co-thread");
module.exports = function *gather(thunks, n){
  n = Math.min(n || 5, thunks.length);
  var ret = [];
  var index = 0;
  function *next() {
    var i = index++;
    ret[i] = {isError: false};
    try {
      ret[i].value = yield thunks[i];
    } catch (err) {
      ret[i].error = err;
      ret[i].isError = true;
    }
    if (index < thunks.length) yield next;
  }
  yield thread(next, n);
  return ret;
};

和co-parallel不同的地方就在于對yield thunks[i]做了一層try catch,然后返回的包含執(zhí)行結(jié)果的對象。

總結(jié)

單單是看parallel的代碼還是很好理解的,但是由于自己co的源碼理解的不好,所以自己在捋清e(cuò)xample的時(shí)候有點(diǎn)混亂了,后來又重新仔細(xì)的看了一遍了co的源碼以及阮一峰的Generator的講解,自己才弄明白。最后再次感謝Ma63d提供的思路。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/86707.html

相關(guān)文章

  • vueparseHTML函數(shù)拿到返回值后的處理源碼解析

      承繼上篇內(nèi)容:下面是parseHTML 函數(shù)源碼解析  varstartTagMatch=parseStartTag();   if(startTagMatch){   handleStartTag(startTagMatch);   if(shouldIgnoreFirstNewline(startTagMatch.tagName,html)){   advance(1);   }   co...

    3403771864 評論0 收藏0
  • 解析ahooks整體架構(gòu)及React工具庫源碼

     這是講 ahooks 源碼的第一篇文章,簡要就是以下幾點(diǎn):  加深對 React hooks 的理解?! W(xué)習(xí)如何抽象自定義 hooks。構(gòu)建屬于自己的 React hooks 工具庫?! ∨囵B(yǎng)閱讀學(xué)習(xí)源碼的習(xí)慣,工具庫是一個(gè)對源碼閱讀不錯(cuò)的選擇。  注:本系列對 ahooks 的源碼解析是基于v3.3.13。自己 folk 了一份源碼,主要是對源碼做了一些解讀,可見詳情?! 〉谝黄饕榻B a...

    3403771864 評論0 收藏0
  • vue parseHTML函數(shù)源碼解析AST基本形成

      vue parseHTML函數(shù)解析器遇到結(jié)束標(biāo)簽,在之前文章中已講述完畢。  例如有html(template)字符串:  <divid="app">   <p>{{message}}</p>   </div>  產(chǎn)出如下:  {   attrs:["id="app"","id...

    3403771864 評論0 收藏0
  • Vue編譯器解析compile源碼解析

      現(xiàn)在我們講compileToFunctions 的使用方法,現(xiàn)在看看內(nèi)容:  //compile   varcompiled=compile(template,options);  其實(shí)真正應(yīng)該講的就是 compile 函數(shù)?! 〗馕?compile  上述代碼在調(diào)用 compile ,其中模板字符串 template ,就是讓選項(xiàng)參數(shù) options 的第二個(gè)參數(shù)傳遞給 compile 函數(shù)...

    3403771864 評論0 收藏0
  • Vue源碼解析(三)-computed計(jì)算屬性&amp;&amp;lazy watcher

    摘要:前言源碼解析一模版渲染源碼解析二雙向綁定官網(wǎng)給出的如下結(jié)果源碼分析判斷參數(shù)是否包含屬性本例中本例中和是函數(shù)監(jiān)聽計(jì)算屬性設(shè)置,延遲執(zhí)行的方法設(shè)置可以通過本例方式訪問計(jì)算屬性對象初始化時(shí)會針對屬性的所有值分別一個(gè)對象,在源碼解析二中有詳細(xì)介 前言 1、Vue源碼解析(一)-模版渲染2、Vue源碼解析(二)-MVVM雙向綁定 demo 官網(wǎng)給出的demo如下 new Vue({ el...

    CoderStudy 評論0 收藏0

發(fā)表評論

0條評論

最新活動(dòng)
閱讀需要支付1元查看
<