由于您的任务可能包含异步代码,因此必须在任务执行完成时向gulp发出信号,表示“异步完成”。
在Gulp 3.x中,您可以不这样做。如果您没有明确地发出异步完成信号,gulp将假定您的任务是同步的,并且一旦您的任务函数返回,它就已经完成了。Gulp 4.x在这方面更加严格。您必须明确发出任务完成信号。
有六种方法可以做到这一点:
1. 返回流
如果你只是想打印一些东西,这并不是一个真正的选项,但这可能是最常用的异步完成机制,因为你通常使用gulp流。以下是一个(相当牵强附会的)示例,演示了如何为您的用例使用它:
var print = require('gulp-print');
gulp.task('message', function() {
return gulp.src('package.json')
.pipe(print(function() { return 'HTTP Server Started'; }));
});
重要的部分在于 return
语句。如果没有返回流,gulp 则无法确定流何时结束。
对于您的使用场景来说,这是一个更加合适的机制。请注意,大多数情况下您不需要自己创建 Promise
对象,它通常会由一个包(例如经常使用的del
包返回一个 Promise
)提供。
gulp.task('message', function() {
return new Promise(function(resolve, reject) {
console.log("HTTP Server Started");
resolve();
});
});
使用 async/await 语法可以进一步简化代码。所有标记为 async
的函数都会隐式返回一个Promise,所以下面的代码也可以工作(如果你的node.js版本支持它):
gulp.task('message', async function() {
console.log("HTTP Server Started");
});
3. 调用回调函数
这可能是您的使用情况中最简单的方法:Gulp会自动将回调函数作为其第一个参数传递给您的任务。完成时只需调用该函数即可:
gulp.task('message', function(done) {
console.log("HTTP Server Started");
done();
});
4. 返回一个子进程
如果您需要直接调用命令行工具,因为没有可用的node.js包装器,则此选项非常有用。它可以解决您的使用情况,但显然我不建议使用(特别是因为它不太可移植):
var spawn = require('child_process').spawn;
gulp.task('message', function() {
return spawn('echo', ['HTTP', 'Server', 'Started'], { stdio: 'inherit' });
});
我从未使用过这种机制,但如果您正在使用 RxJS,它可能很有用。如果您只是想打印一些东西,那么这可能有点过度设计:
var of = require('rxjs').of;
gulp.task('message', function() {
var o = of('HTTP Server Started');
o.subscribe(function(msg) { console.log(msg); });
return o;
});
像之前一样,我将其包含在内是为了完整性,但除非您已经出于某种原因在使用 EventEmitter
,否则您不会真正使用它。
gulp.task('message3', function() {
var e = new EventEmitter();
e.on('msg', function(msg) { console.log(msg); });
setTimeout(() => { e.emit('msg', 'HTTP Server Started'); e.emit('finish'); });
return e;
});
webpack-stream
出现了问题,请使用以下链接:https://github.com/shama/webpack-stream/issues/34#issuecomment-478602446 - B3none