如何让 Gulp4 等待文件写入任务竞争?

How to get Gulp4 to wait for file write tasks to compete?

我正在尝试使用 Gulp 4(具体版本信息见下文)编写一个工作流,它将

  1. 查看本地文件夹中的 .html 文件
  2. 根据 table
  3. 将多个 table 拆分为单独的 .html 文件
  4. 将上述 tables 转换为 .csv 以供进一步处理
  5. 清理临时目录所有这些文件也被转储了。

我 运行 遇到的问题是,无论我尝试什么,我都无法让清理任务等待其余任务将文件写入磁盘。我已经尝试嵌套数据收集功能,包括所有更改方法到一个长流中,以及此处和其他地方提供的一些其他笨拙的解决方案 - none 尽管它们有效。任何指针都会有很大的帮助。

var gulp = require('gulp');
var exec = require('child_process').exec;
var rename = require('gulp-rename');
var inject = require('gulp-inject-string');
var htmlSplit = require('gulp-htmlsplit');
var del = require('del');

// Clean all non-csv files from ./data/temp
function clean() {
  return del(['data/temp/*', '!data/temp/*.csv']);
}

// Convert HTML tables to CSV files
function convertCSV(filename) {
  return exec('node node_modules/html-table-to-csv data/temp/' + filename + '.html data/temp/' + filename + '.csv');
}

// Move a renamed copy of original report to .data/temp/
function getData() {
  return gulp.src('data/report/*.html')
    .pipe(rename('injected.html'))
    .pipe(gulp.dest('data/temp'));
}

// Inject split start comments before each <table> tag
function injectBefore() {
  return gulp.src('data/temp/*.html')
    .pipe(inject.beforeEach('<table', '<!-- split table.html -->\n'))
    .pipe(gulp.dest('data/temp'));
}

// Inject split stop comments after each </table> tag
function injectAfter() {
  return gulp.src('data/temp/*.html')
    .pipe(inject.afterEach('</table>', '\n<!-- split stop -->'))
    .pipe(gulp.dest('data/temp'));
}

// Split each table into its own HTML file for CSV conversion
function htmlCSV(done) {
  var i = 0;
  return gulp.src('data/temp/injected.html')
    .pipe(htmlSplit())
    .pipe(rename(function(file) {
      // Append unique number to end of each HTML file
      file.basename += i >= 9 ? ++i : '0' + ++i;
      // Send unique numbered HTML file to convertCSV()
      convertCSV(file.basename);      
    }))
    .pipe(gulp.dest('data/temp'));
  done();
}

gulp.task('default', gulp.series(getData, injectBefore, injectAfter, htmlCSV, clean));

// FILE STRUCTURE
// analytics
// |_bower_components
// |_data
//   |_report  <-- Original report in HTML dumped here
//   |_temp    <-- Injected and converted files dumped here
// |_node_modules
// |_gulpfile.js and other files
// 
// Gulp - CLI version 1.2.2
// Gulp - Local version 4.0.0-alpha.2
// Node - v6.9.5
// NPM  - 3.10.10
// OS   - Windows 7 6.1.7601 Service pack 1 Build 7601

我删除了常规 gulp 插件和实际的 csv 转换,因为那只是 child_process 执行。

您的代码的主要问题是 Node 核心 child_process.exec 是 Asnyc,除非您添加回调,否则不会 return 结束。将其替换为 sync-exec 将允许同步过程调用,因为 gulp-rename 回调没有回调。

var gulp = require('gulp');
var exec = require('sync-exec');
var rename = require('gulp-rename');
var del = require('del');

// Clean all non-csv files from ./data/temp
function clean() {
  return del(['temp']);
}

// Convert HTML tables to CSV files
function convertCSV(filename) {
  // return exec('node node_modules/html-table-to-csv data/temp/' + filename + '.html data/temp/' + filename + '.csv');
  return exec('sleep 5;');
}

// Move a renamed copy of original report to .data/temp/
function getData() {
  return gulp.src('t.html')
    .pipe(gulp.dest('temp/'));
}

// Split each table into its own HTML file for CSV conversion
function htmlCSV() {
  var i = 0;
  return gulp.src('t.html')
    .pipe(rename(function(file) {
      // Append unique number to end of each HTML file
      file.basename += i >= 9 ? ++i : '0' + ++i;
      // Send unique numbered HTML file to convertCSV()
      convertCSV(file.basename);
    }))
    .pipe(gulp.dest('dist'));
}

gulp.task('default', gulp.series(getData, htmlCSV, clean));

使用 es7 async/await 语法以及 util.promisify 等待它完成:

const util = require('util');
const exec = util.promisify(require('child_process').exec);

// Convert HTML tables to CSV files
async function convertCSV(filename) {
  return await exec('node node_modules/html-table-to-csv',
    ['data/temp/' + filename + '.html',
    'data/temp/' + filename + '.csv']);
}

不需要第三方库