简体   繁体   中英

How a gulp function can know that functions called inside it are finished?

I'm writing a gulp task that copy sass files into a tmp folder and then create css.

function copy_sass(done) {

  var conponments = setup.conponments;
  var sassList = config.conponments.sass;
  var mainPath = config.path.src.sass.main;
  var rootPath = config.path.src.sass.root;
  var source = getPaths(conponments, sassList, mainPath);// get a filtered list of path
  var destination = config.path.tmp.sass_tmp;

  copyPath(mainPath + 'mixin/**', destination + 'main/mixin/');
  copyPath(mainPath + 'settings/**', destination + 'main/settings/');
  copyPath(rootPath + 'style.scss', destination);
  copyPath(source, destination + 'main/conponment/');

  done();
};

function css_build(done) {
  var source = config.path.tmp.sass_tmp + '**/*.scss';
  var destination = config.path.tmp.css.root;

  return src(source)
    .pipe(bulkSass())
    .pipe(sass())
    .pipe(csscomb())
    .pipe(cssbeautify({indent: '  '}))
    .pipe(autoprefixer())
    .pipe(gulp.dest(destination));
  done();
};

function copyPath(source, destination) {
  return src(source)
    .pipe(dest(destination));
};

exports.getcss = series(
  copy_sass,
  css_build
);

exports.filter = filter_tmp_sass;

exports.css = css_build;

When I call functions in series with the task getcss, gulp don't seem to wait before the copy task is finished and css_build do nothing because the paths are not already copied.

When I launch the copy task and then the css task manually, all is working. So I think that the problem is that the copy_sass function is considered as finished before the end of the copyPath functions, and then css_build is launched before the paths are copied.

What I expect is that the getcss task wait until the copy_sass function and the copyPath function inside it are finished before launch css_build.

Node libraries handle asynchronicity in a variety of ways.

The Gulp file streams (usually started with src() ) work asynchronously. This means, that they start some kind of work, but instantly return when being called. This is the reason why you always need to return the stream from the task, so that Gulp knows when the actual work of the task is finished, as you can read in the Gulp documentation :

When a stream, promise, event emitter, child process, or observable is returned from a task, the success or error informs gulp whether to continue or end.

Regarding your specific example, in your task copy_sass you call copyPath multiple times. The copying is started, but the methods instantly return without waiting for completion. Afterwards, the done callback is called telling Gulp that the task is done.

To ensure task completion, you need to return every single stream to Gulp. In your example, you could create a separate task for each copy operation and aggregate them via series() or even parallel() :

function copyMixin() {
    return src('...').pipe(dest(...))
}

function copySettings() {
    return src('...').pipe(dest(...))
}

// ...

var copySass = parallel(copyMixin, copySettings, ...)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM