我想构建一个gulp任务,在运行之前有条件地手动调用其他任务。在看到gulp.run('task')
被弃用之后,我最终得到了这个基本结构:
const build = {
server: () => {
return gulp.src(files.server)
...
.pipe(gulp.dest(files.outDir))
},
web: () => {
return gulp.src(files.web)
...
.pipe(gulp.dest(files.outDir))
}
}
gulp.task('serve', () => {
// run the server and if necessary, force it to stop first
const start = () => expressServer.start('./dist/main.js')
// don't try to run if build hasn't been run first
try {
fs.statSync('./dist/main.js') // throws an exception if the file doesn't exist
start()
} catch (err) {
// ----- TODO in parallel; build server and web
// afterwards; run server iff there were no errors
if (failed)
console.error(err)
else
start()
}
})
看起来调用build.server()
或build.web()
确实会运行gulp任务,但函数会立即返回 - 我想这意味着这些函数的主体是异步运行的?
任何人都可以帮助我理解:
gulp.src(...). ... .gulp.dest(...)
链实际上会返回什么?正如我怀疑的那样,gulp是异步运行这些操作的吗?答案 0 :(得分:1)
我发现DefinitelyTyped(Typescript)文件通常有助于弄清楚发生了什么。据我所知:
gulp.src
function会提供NodeJS.ReadWriteStream
; ...Stream
都有一个pipe
方法,它接收一个流并返回一个相同/相似(?)类型。< / LI>
因此,基本上,您返回gulp.src
的结果(管道位不会更改返回值的类型),这是一个节点流。
这基本上意味着您可以运行server
和web
任务,并使用finish
callbacks of the streams those tasks return仅在成功完成后才采取措施。
作为一个脚注,尽管我对精确的工作方式不满意,但我认为merge-stream
也可能有所帮助,如果您需要等待多个流完成。
这是一个基本示例(基于您的代码,减去try..catch
位):
var gulp = require("gulp");
var mergeStream = require("merge-stream");
const build = {
server: () => {
process.stdout.write("MYMESSAGE: Server...\n");
return gulp.src("src/nonexistent/server.js").pipe(gulp.dest("./build/server"));
},
web: () => {
process.stdout.write("MYMESSAGE: Web...\n");
return gulp.src("src/web.js").pipe(gulp.dest("./build/server"));
}
}
gulp.task("serve", () => {
const start = () => process.stdout.write("MYMESSAGE: Starting!\n");
try {
throw new Error("Simulated error!");
} catch(err) {
// In parallel build server and web, afterwards run
// server iff there were no erros.
mergeStream(build.server(), build.web())
.on("error", () => console.error(err))
.on("finish", () => start());
}
});