gulp.task
方法用来定义任务,内部使用的是Orchestrator,其语法为:
gulp.task(name[, deps], fn)
//定义一个有依赖的任务
gulp.task('mytask', ['array', 'of', 'task', 'names'], function() {
// Do something
});
gulp.task()这个API没什么好讲的,但需要知道执行多个任务时怎么来控制任务执行的顺序。
gulp中执行多个任务,可以通过任务依赖来实现。例如我想要执行one,two,three这三个任务,那我们就可以定义一个空的任务,然后把那三个任务当做这个空的任务的依赖就行了:
//只要执行default任务,就相当于把one,two,three这三个任务执行了
gulp.task('default',['one','two','three']);
如果任务相互之间没有依赖,任务会按你书写的顺序来执行,如果有依赖的话则会先执行依赖的任务。
但是如果某个任务所依赖的任务是 异步 的,就要注意了,gulp并不会等待那个所依赖的异步任务完成,而是会接着执行后续的任务。例如:
gulp.task('one',function(){//这里没有 cb 函数
//one是一个异步执行的任务
setTimeout(function(){
console.log('one is done')
},5000);
});
//two任务虽然依赖于one任务,但并不会等到one任务中的异步操作完成后再执行
gulp.task('two',['one'],function(){
console.log('two is done');
});
//two is done
//one is done
上面的例子中我们执行two任务时,会先执行one任务,但不会去等待one任务中的异步操作完成后再执行two任务,而是紧接着执行two任务。所以two任务会在one任务中的异步操作完成之前就执行了。
那如果我们想等待异步任务中的异步操作完成后再执行后续的任务,该怎么做呢?
有三种方法可以实现:
第一:在异步操作完成后执行一个回调函数来通知gulp这个异步任务已经完成,这个回调函数就是任务函数的第一个参数。
gulp.task('one',function(cb){ //cb为任务函数提供的回调,用来通知任务已经完成
//one是一个异步执行的任务
setTimeout(function(){
console.log('one is done');
cb(); //执行回调,表示这个异步任务已经完成,只是起一个通知的作用,并不是指向task two 的 fun
},5000);
});
//这时two任务会在one任务中的异步操作完成后再执行
gulp.task('two',['one'],function(){
console.log('two is done');
});
//one is done
//two is done
第二:定义任务时返回一个流对象。适用于任务就是操作gulp.src获取到的流的情况。
gulp.task('one',function(cb){
var stream = gulp.src('client/**/*.js')
.pipe(dosomething()) //dosomething()中有某些异步操作
.pipe(gulp.dest('build'));
return stream;
});
gulp.task('two',['one'],function(){
console.log('two is done');
});
第三:返回一个promise对象,例如
var Q = require('q'); //一个著名的异步处理的库 https://github.com/kriskowal/q
gulp.task('one',function(cb){
var deferred = Q.defer();
// 做一些异步操作
setTimeout(function() {
deferred.resolve();
}, 5000);
return deferred.promise;
});
gulp.task('two',['one'],function(){
console.log('two is done');
});
gulp.task()就这些了,主要是要知道当依赖是异步任务时的处理。
Task 流程控制,当然也可以使用一些 gulp 的插件,比如 gulp-sequence 或是 run-sequence.
官方API 文档: https://www.npmjs.com/package/gulp-sequence
简单说明一下使用方法:
var gulp = require('gulp')
var gulpSequence = require('gulp-sequence')
gulp.task('a', function (cb) {
//... cb()
})
gulp.task('b', function (cb) {
//... cb()
})
gulp.task('c', function (cb) {
//... cb()
})
gulp.task('d', function (cb) {
//... cb()
})
gulp.task('e', function (cb) {
//... cb()
})
gulp.task('f', function () {
// return stream
return gulp.src('*.js')
})
// usage 1, recommend
// 1. run 'a', 'b' in parallel;
// 2. run 'c' after 'a' and 'b';
// 3. run 'd', 'e' in parallel after 'c';
// 3. run 'f' after 'd' and 'e'.
gulp.task('sequence-1', gulpSequence(['a', 'b'], 'c', ['d', 'e'], 'f'))
// usage 2
gulp.task('sequence-2', function (cb) {
gulpSequence(['a', 'b'], 'c', ['d', 'e'], 'f', cb)
})
// usage 3
gulp.task('sequence-3', function (cb) {
gulpSequence(['a', 'b'], 'c', ['d', 'e'], 'f')(cb)
})
gulp.task('gulp-sequence', gulpSequence('sequence-1', 'sequence-2', 'sequence-3'))
另外, run-sequence 与 gulp-sequence 操作方式差不多.
官方API 文档: https://www.npmjs.com/package/run-sequence
简单使用方式 :
var gulp = require('gulp');
var runSequence = require('run-sequence');
var del = require('del');
var fs = require('fs');
// This will run in this order:
// * build-clean
// * build-scripts and build-styles in parallel
// * build-html
// * Finally call the callback function
gulp.task('build', function(callback) {
runSequence('build-clean',
['build-scripts', 'build-styles'],
'build-html',
callback);
});