Search code examples
javascriptasynchronousgulpgulp-sass

Run gulp methods inside a single task asynchronously


var gulp = require('gulp');
var gutil = require('gulp-gutil');
var sass = require('gulp-sass');
var rename = ('gulp-rename');

gulp.task('test', function() {
    function compileSass() {
        return new Promise(function(resolve, reject) {
            gulp.src('test.scss')
                .pipe(sass())
                .pipe(gulp.dest('.'))
                    .on('end', resolve());
        });
    }

    compileSass().then(function(result) {
        gulp.src('test.css')
            .pipe(rename('testCopy.css'))
            .pipe(gulp.dest('.'));
    })
    .catch(function(error) {
        gutil.log(error);
    });    
});

All I'm trying to do is run these gulp.src methods asynchronously so that the test.scss file will get compiled before test.css gets copied by the next gulp.src method. I've tried using callbacks, promises (in this example), and async/await, but I can never get test.css and testCopy.css together on a fresh run. I understand that if I just put these two gulp.src methods into separate tasks, I'd get that asynchronous functionality I'm seeking, but it would be very helpful if I didn't have to make a new task every single time I want to modify/copy a file. Thanks!


Solution

  • var gulp = require('gulp');
    var gutil = require('gulp-gutil');
    var sass = require('gulp-sass');
    var rename = ('gulp-rename');
    
    gulp.task('test', function() {
        function compileSass() {
            return new Promise(function(resolve, reject) {
                gulp.src('test.scss')
                    .pipe(sass())
                    .pipe(gulp.dest('.'))
                        .on('end', resolve); // changed resolve() to just resolve
            });
        }
    
        compileSass().then(function(result) {
            gulp.src('test.css')
                .pipe(rename('testCopy.css'))
                .pipe(gulp.dest('.'));
        })
        .catch(function(error) {
            gutil.log(error);
        });    
    });
    

    I managed to find my issue...I just had to change resolve() to resolve. Gonna be honest, not really sure why that works, but it works now. If you wanted to use resolve() for whatever reason, I tried putting it in an arrow function which worked as well:

    .on('end', () => resolve() );
    
    // OR
    
    .on('end', function() {
      resolve();
    });
    
    // OR
    
    .on('end', resolve);
    

    Edit: I know asynchronous shit can get confusing when starting to learn this stuff, so here's an example when using a callback instead of a promise.

    function compileSass(callback) {
          gulp.src('test.scss')
              .pipe(sass())
              .pipe(gulp.dest('.'))
                  .on('end', callback);
      }
    
      compileSass(function() {
          gulp.src('test.css')
              .pipe(rename('testCopy.css'))
              .pipe(gulp.dest('.'));
      });