Gulp 任务中`return` 语句和`callback` 参考的用途

我无法让 gulp run-sequence 执行我给它的两个函数(它只会执行其中一个.我有这样的事情:

gulp.task('wire', function(){gulp.src('./index.html').pipe(wiredep()).pipe(gulp.dest('.'));});var filesToInject = ['./app/**/*.js', './app/**/*.css'];gulp.task('注入', function (){var target = gulp.src('./index.html');var sources = gulp.src(filesToInject, {read: false});返回target.pipe(注入(来源)).pipe(gulp.dest('.'));});gulp.task('wire-inject', function(callback){序列('wire','inject',回调);});

那只会运行 inject 任务.只有当我在 wire 任务中的 gulp.src 之前添加一个 return 时,它才会执行.我还在两个函数参数中添加了回调,并将其传递给每个 文档.

gulp.task('wire', function(callback){gulp.src('./index.html').pipe(wiredep()).pipe(gulp.dest('.'), 回调);});var filesToInject = ['./app/**/*.js', './app/**/*.css'];gulp.task('inject', 函数(回调){var target = gulp.src('./index.html');var sources = gulp.src(filesToInject, {read: false});返回target.pipe(注入(来源)).pipe(gulp.dest('.'), 回调);});

这并没有引发任何错误,但是如果我把它拿出来它不会改变任何东西.这个 return 语句做了什么神奇地使我的序列完全运行.文档中的这些回调是什么,我只是通过不带括号的引用来执行它们?即使它们看似什么都不做,我是否仍然需要它们?

解决方案

Gulp 需要知道异步任务何时完成.您有 3 种方法可以做到这一点:

  1. 返回一个事件流,这就是当你的任务函数中有 return gulp.src(...).pipe(...); 时你所做的.p>

  2. 返回一个承诺.

  3. 让定义你任务的函数带一个参数.Gulp 将使用回调函数调用您的函数,您应该在任务结束时调用该回调函数.

如果您不这样做,那么 Gulp 将不会知道该任务是异步的.因此,它会在其函数返回后立即认为任务已完成.这会带来各种后果.Gulp 可以在任务完成之前退出.或者它可以在任务 A 完成之前启动依赖于任务 A 的任务 B.在某些情况下,您可能立即看不到问题,但随着您的 gulpfile 变得越来越复杂,您出现不良行为的机会也越来越多.run-sequence 并不特殊:它需要知道任务何时完成才能正确完成工作.

请注意,您在问题中显示的此代码中的 callback 是无用的:

return target.pipe(inject(sources)).pipe(gulp.dest('.'), 回调);

callback 不会被调用.将其替换为 function () { console.log("Hello!");打回来();}.您不会在控制台上看到 Hello!,因为未调用回调.但是,代码确实可以正常工作,因为您返回了流.Gulp 使用您返回的流来确定任务结束,而不是回调(无论如何都不会调用).

I was having trouble getting gulp run-sequence to execute both functions that i gave it (it would only execute one of them. I had something like this:

gulp.task('wire', function(){
  gulp.src('./index.html')
    .pipe(wiredep())
    .pipe(gulp.dest('.'));
});

var filesToInject = ['./app/**/*.js', './app/**/*.css'];
gulp.task('inject', function (){
  var target = gulp.src('./index.html');
  var sources = gulp.src(filesToInject, {read: false});
  return target.pipe(inject(sources))
    .pipe(gulp.dest('.'));
});

gulp.task('wire-inject',  function(callback){
    sequence('wire', 'inject', callback);
});

That would only run the inject task. Only when I added a return before gulp.src in the wire task would it execute. I also added callback in both function params and passed it to the last pipe in both tasks per the documentation.

gulp.task('wire', function(callback){
  gulp.src('./index.html')
    .pipe(wiredep())
    .pipe(gulp.dest('.'), callback);
});

var filesToInject = ['./app/**/*.js', './app/**/*.css'];
gulp.task('inject', function (callback){
  var target = gulp.src('./index.html');
  var sources = gulp.src(filesToInject, {read: false});
  return target.pipe(inject(sources))
    .pipe(gulp.dest('.'), callback);
});

That did not throw any errors, however it doesn't change anything if I take it out. What does this return statement do that magically makes my sequence run completely. What are these callbacks in the documentation that I just pass a reference to with out parentheses to execute them? Do I still need them even though they seemingly do nothing?

解决方案

Gulp needs to know when an asynchronous task is done. You have 3 ways to do this:

  1. Return an event stream, which is what you do when you have return gulp.src(...).pipe(...); in your task's function.

  2. Return a promise.

  3. Have the function that defines you task take a parameter. Gulp will call your function with a callback that you should call when the task is over.

If you do not do this, then Gulp will not know that the task is asynchronous. So it will consider the task done as soon as its function returns. This has all kinds of consequences. Gulp could exit before a task is done. Or it could start a task B that depends on task A before task A is complete. In some cases, you may not see a problem immediately but as your gulpfile gets more complex, you run more chances of getting bad behavior. run-sequence is not special: it needs to know when a task is complete to do its job correctly.

Note that callback in this code which you show in your question is useless:

return target.pipe(inject(sources))
    .pipe(gulp.dest('.'), callback);

callback won't be called. Replace it with function () { console.log("Hello!"); callback(); }. You won't see Hello! on the console because the callback is not called. However, the code does work overall because you return the stream. Gulp uses the stream you return to determine that the task is over, not the callback (which is never called anyway).

相关文章