Defer node stream processing

Delay chain of piped streams until a promise is resolved

There might be times when you have a chain of piped streams where you want to delay a part of the chain until a promise is resolved. You can do this with a function that returns a simple Transform stream.

function waitFor(promise) {
  return stream.Transform({
    objectMode: true,
    transform: function(file, enc, cb) {
      var self = this;
      promise.then(function() {
        self.push(file);
        cb();
      }, function(err) {
        cb(new Error(err));
      });
    }
  });
}

You would need to pipe to and from the return value of the above function, and it will effectively delay the downstream piping until the passed promise is resolved. This can be useful in a gulp task where you don't want to split it up into sub-tasks, but still want one part of a stream to be processed after another.

As a example, taking part of the gulpfile for this blog, I defer publishing html files until images and stylesheets have been uploaded, so any visitors mid-update don't see a broken site.

gulp.src('blog/**/*.html', {cwd: BUILD_DIR, base: BUILD_DIR})
  .pipe(awspublish.gzip())
  .pipe(waitFor(Promise.all([binaryResourcesDone, textResourcesDone])))
  .pipe(publish({
    'Cache-Control': 'max-age=' + 60 * 5 + ', no-transform, public'
  }));