开源Nodejs项目推荐gulp核心模块:Orchestrator
Posted Node全栈
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了开源Nodejs项目推荐gulp核心模块:Orchestrator相关的知识,希望对你有一定的参考价值。
目录
为什么要介绍这个模块?
简介和基本用法
它是如何做到以最大并发执行的?
作业依赖链是如何计算的?
事件回调
如何实现一个简易gulp?
最后点评一下
Why?
gulp已经是nodejs用的最多,排名前10的著名模块了,而Orchestrator模块是gulp的核心模块,如果你也是gulp使用者,那么你有必要了解一下gulp的实现原理,以及为什么它比较快
依赖
https://github.com/gulpjs/gulp/blob/master/package.json#L36
代码
https://github.com/gulpjs/gulp/blob/master/index.js
'use strict';
var util = require('util');
var Orchestrator = require('orchestrator');
var gutil = require('gulp-util');
var deprecated = require('deprecated');
var vfs = require('vinyl-fs');
function Gulp() { Orchestrator.call(this);
}
util.inherits(Gulp, Orchestrator);
Gulp.prototype.task = Gulp.prototype.add;
Gulp.prototype.run = function() { // `run()` is deprecated as of 3.5 and will be removed in 4.0 // Use task dependencies instead // Impose our opinion of "default" tasks onto orchestrator var tasks = arguments.length ? arguments : ['default']; this.start.apply(this, tasks);
};
中
function Gulp() { Orchestrator.call(this);
}
util.inherits(Gulp, Orchestrator)
这里说明Gulp继承自Orchestrator
Gulp.prototype.task = Gulp.prototype.add;
这里很明显gulp里的task方法就是Orchestrator里的add方法的别名。其他依此类推,大家去源码里翻吧。
so,我才说它是gulp核心模块的。
Intro
https://github.com/robrich/orchestrator
A module for sequencing and executing tasks and dependencies in maximum concurrency
翻译过来的意思
sequencing 顺序
executing tasks 执行任务
dependencies 支持依赖任务
最后一句才是最牛最核心的的:in maximum concurrency即以最大的并发能力来执行
Usage
1) Get a reference:
var Orchestrator = require('orchestrator');
var orchestrator = new Orchestrator();
reference是对象引用,也就是实例化Orchestrator对象的方式。
2) Load it up with stuff to do:
orchestrator.add('thing1', function(){ // do stuff});orchestrator.add('thing2', function(){ // do stuff
});
给orchestrator实例增加要执行的task(任务),add方法就2个参数
参数1:是任务名称
参数2:是具体要做的事儿,即task具体内容
简而言之:作业定义
stuff这个词的意思是: 填塞,填充;塞入
3) Run the tasks:
orchestrator.start('thing1', 'thing2', function (err) { // all done
});
这个就没啥好说的,执行任务,上面定义了’thing1’, ‘thing2’,需要在start里运行才可以执行。
另外api还有关于promise和stream的支持
它是如何做到以最大并发执行的?
看着挺吓唬人的,什么以最大并发,其实也很简单
见源码
https://github.com/robrich/orchestrator/blob/master/index.js
var Orchestrator = function () { EventEmitter.call(this); // call this when all tasks in the queue are done this.doneCallback = undefined; // the order to run the tasks this.seq = []; // task objects: name, dep (list of names of dependencies), fn (the task to run) this.tasks = {}; // is the orchestrator running tasks? .start() to start, .stop() to stop this.isRunning = false;
};
这里的this上定义的4个变量是最核心的,其实和并发执行有关的seq
// the order to run the tasks
this.seq = [];
js的数组[]
是非常灵活的数据结构,它既可以队列也可以栈,如果不明白,自己去补基础。
注释上说,用于保存执行task的顺序,为什么这么说呢?
task是通过this.tasks定义
start里会有多个task
每个task又有可能有多个依赖
每个依赖又可能有多个依赖
所以如果执行多个tasks,你肯定要把里面的所有tasks放到seq这个队列里。在队列里的好处是,如果计算机有能力执行,它就从队列里取走一个,如果还有能力就再取走一个,所以这其实是in maximum concurrency即以最大的并发能力来执行。
上面讲了各种作业和作业依赖的问题,那么如果依赖里还有依赖,依赖的依赖里还有依赖,那么这个执行链还怎么计算呢?
作业依赖链是如何计算的?
答案见sequencify模块,其实就是一个简单的递归
源码见 https://github.com/robrich/sequencify
事件回调
var events = ['start','stop','err','task_start','task_stop','task_err','task_not_found','task_recursion'];
具体实现
var Orchestrator = function () { EventEmitter.call(this); // call this when all tasks in the queue are done this.doneCallback = undefined; // the order to run the tasks this.seq = []; // task objects: name, dep (list of names of dependencies), fn (the task to run) this.tasks = {}; // is the orchestrator running tasks? .start() to start, .stop() to stop this.isRunning = false;
};
看这句
EventEmitter.call(this);
此处比较简单,在nodejs这样是非常常见的处理方式。此处不细讲了
如何实现一个简易gulp?
gulp.task('default', function() { // place code for your default task here
});
然后后执行gulp default
就会调用default task。
如果换成是orchestrator呢?
var Orchestrator = require('orchestrator');
var orchestrator = new Orchestrator();
orchestrator.add('hello', function(){ // do stuff console.log('this is hello task...\n');
});
orchestrator.add('default', function(){ // do stuff console.log('this is default task...\n');
});
module.exports = orchestrator;
然后写个命令行,解析里面的argv来执行
#!/usr/bin/env node // var argv = process.argv.slice(2, process.argv.length) var argv = process.argv; argv.shift(); argv.shift(); console.log(argv + '\n'); console.log('start\n'); var gulp = require('./task') gulp.start(argv, function(){ console.log('end'); })
然后测试
node index.js default
or
➜ mygulp git:(master) ✗ node index.js default hellodefault,hello startthis is default task...
this is hello task...
end
剩下的就是通过npm实现cli功能处理了。
那么作业依赖呢?
gulp.task('images', ['clean'], function() { ...
});
在task.js里
orchestrator.add('dep', ['hello'], function(){ // do stuff console.log('this is default task...\n');
});
然后执行
➜ mygulp git:(master) ✗ node index.js dep dep startthis is hello task...
this is default task...
end
代码:https://github.com/i5ting/nodejs-open-source-recommendation/tree/master/examples/mygulp
点评
代码不多,但东西比较多
另外api还有关于event,promise和stream等的支持
遵循node的小而美哲学
测试mocha+should测试用例非常丰富
文档,代码都比较规范
在某些依赖key:function的场景下,Orchestrator是一个非常的选择。另外以最大并发跑task的特性也是大的实用场景。
全文完
如果想参与评论,请点击原文链接,进入国内最专业的cnode论坛
以上是关于开源Nodejs项目推荐gulp核心模块:Orchestrator的主要内容,如果未能解决你的问题,请参考以下文章