Gulp 中异步任务的处理

云贤力 114个月前 提问 源自: 自动化工具Gulp|gulp api
0

异步任务操作完成后再执行后续任务,其中一种方法是返回一个流对象,这个怎么理解?

gulp.task('one',function(cb){
  var stream = gulp.src('client/**/*.js')
      .pipe(exec()) //exec()中有某些异步操作
      .pipe(gulp.dest('build'));
    return stream;
});

gulp.task('two',['one'],function(){
  console.log('two is done');
});

  • 0
    ciga 114个月前 回答

    如果你有多个任务,通常需要它们按照一定次序执行。比如:

    var gulp = require("gulp");
    gulp.task("task1",function(){ 
      setTimeout(function(){
        console.log("---------------task1---------------");  
      },2000);
    });
    gulp.task("task2",["task1"],function(){ 
      setTimeout(function(){
        console.log("---------------task2---------------");  
      },1000);
    });
    gulp.task("default",["task1","task2"],function(){
      console.log("---------------default task---------------");
    });

    你肯定期望,在默认任务default开始执行之前,任务task2执行已经确保执行完成;而任务task2开始执行前,也应当确保task1已经执行完成。

    但是你执行上面的gulpfile.js,得不到你想要的结果。实际的结果恰恰相反:default task -> task2 -> task1

    这是因为task1和task2都是异步的,gulp没法判断这些异步任务是否已经完成。除非,你使用以下三种办法之一:

    1. 使用回调函数通知gulp任务完成

    在定义一个gulp的任务时,gulp会传入一个回调函数作为参数,当你的任务完成时,调用这个回调函数,就可以通知gulp你的任务的确完成了:

    var gulp = require("gulp");
    gulp.task("task1",function(cb){ 
      setTimeout(function(){
        console.log("---------------task1---------------");  
        cb();
      },2000);
    });
    gulp.task("task2",["task1"],function(cb){ 
      setTimeout(function(){
        console.log("---------------task2---------------");  
        cb();
      },1000);
    });
    gulp.task("default",["task1","task2"],function(){
      console.log("---------------default task---------------");
    });

    2.让任务返回流

    如果你定义的gulp任务,返回的是流(通常来讲,gulp的插件返回的都是流对象,这样才可以级联起来),那么gulp也可以确定你的任务何时执行完成,从而确保任务的先后执行顺序。这就是你说的情况。

    3. 让任务返回Promise

    如果你定义的gulp任务,返回的是Promise对象,那么gulp也可以确定你的任务何时执行完成,从而确保执行顺序:

    var gulp = require("gulp");
    var Promise = require("bluebird");
    gulp.task("task1",function(){
      return new Promise(function(resolve,reject){
        setTimeout(function(){
          console.log("---------------task1---------------");  
          resolve();
        },2000);
      })
    });
    gulp.task("task2",["task1"],function(){ 
      return new Promise(function(resolve,reject){
        setTimeout(function(){
          console.log("---------------task2---------------");  
          resolve();
        },1000);  
      });
    });
    gulp.task("default",["task1","task2"],function(){
      console.log("---------------default task---------------");
    });
    总结:当gulp启动多个任务时,它默认是并发方式启动的。如果你希望各个任务以串行的方式执行,必须显式地用上面三种方式之一告诉gulp。

    进一步参考:https://github.com/gulpjs/gulp/blob/master/docs/API.md#async-task-support
    Note: By default, tasks run with maximum concurrency -- e.g. it launches all the tasks at once and waits for nothing. If you want to create a series where tasks run in a particular order, you need to do two things: