Gulp:调用一个异步函数,该函数从转换函数中提供自己的回调
Gulp: call an async function which provides its own callback from within a transform function
我想创建一个用于 Gulp 中的 pipe() 调用的函数,它可以将 xlsx 文件转换为 json。
我在 gulp 3 中使用 NPM 包 'excel-as-json',但是 Gulp 4 迫使我真正理解它在做什么 ;-)
六个小时后,由于缺乏 js/async/streaming 知识,我无法让它工作,这激发了我的好奇心。
代码如下:
paths = {excel_sourcefiles: "./sourcefiles/*.xls*", excel_targetdir_local_csvjson: "./targetfiles_local/*.*"}
var replaceExt = require('replace-ext');
var PluginError = require('plugin-error')
var gulpFunction = require('gulp-function').gulpFunction // default ES6 export
var through = require("through2")
var convertExcel = require('excel-as-json').processFile;
var changed = require('gulp-changed');
var assign = Object.assign || require('object.assign');
var notify = require('gulp-notify');
var gulpIgnore = require('gulp-ignore');
var rename = require('gulp-rename');
gulp.task('excel-to-jsoncsv', function() {
return gulp.src(paths.excel_sourcefiles)
// .pipe(debug())
.pipe(gulpIgnore.exclude("*\~*")) // Ignore temporary files by Excel while xlsx is open
.pipe(gulpIgnore.exclude("*$*")) // Ignore temporary files by Excel while xlsx is open
.pipe(plumber({errorHandler: notify.onError('gulp-excel-to-jsoncsv error: <%= error.message %>')}))
.pipe(changed(paths.excel_targetdir_local_glob, { extension: '.csv' }))
.pipe(GulpConvertExcelToJson()) // This is where the magic should happen
.pipe(rename({ extname: '.csv' })) // Saving as .csv for SharePoint (does not allow .json files to be saved)
.pipe(gulp.dest(paths.excel_targetdir_local))
});
function GulpConvertExcelToJson() {
return through.obj(function(chunk, enc, callback) {
var self = this
if (chunk.isNull() || chunk.isDirectory()) {
callback() // Do not process directories
// return
}
if (chunk.isStream()) {
callback() // Do not process streams
// return
}
if (chunk.isBuffer()) {
convertExcel(chunk.path, null, null, // Converts file found at `chunk.path` and returns (err, `data`) its callback.
function(err, data) {
if (err) {
callback(new PluginError("Excel-as-json", err))
}
chunk.contents = new Buffer(JSON.stringify(data))
self.push(chunk)
callback()
// return
})
} else {
callback()
}
})
}
我(现在)知道还有其他 excel > json gulp 模块可以让我在不编写自己的模块的情况下解决这个问题,但我想了解我在这里应该做些什么。
返回的错误是'Did you forget to signal Async completion?',我尽量不这样做。但是,我尝试用 var self = this
修复错误 'this.push is not a function' 的尝试可能不是我应该做的。
查看 gulp-zip 之类的示例让我了解了不熟悉的符号,使我无法通过自学来解决这个问题。
总结:
- 我将如何在 through.obj 函数调用期间调用异步函数,其中块的内容使用(不受我控制的)异步函数更新,该函数仅向我提供回调(错误,数据)?
这个问题来自 excel
库。 The end
event should be finish
.
尝试失败
我做了以下操作,安装修改后的 excel.js:
rm -rf node_modules/excel
git clone https://github.com/bdbosman/excel.js node_modules/excel
cd node_modules/excel && npm i && cd ../..
这还不够,因为 excel-as-json
使用旧版本的 excel
。
要么您必须修改 excel-as-json
模块,使用 excel@1.0.0
(合并请求请求后),或者手动编辑 node_modules 中的文件。我这里介绍第二种方式。
临时解决方案
安装模块后编辑 excel
文件。
我用过:
sed -i "s/'end'/'finish'/g" node_modules/excel/excelParser.js
然后我运行:
$ gulp excel-to-jsoncsv
[19:48:21] Using gulpfile ~/so-question-gulp-async-function-call-xlsx/gulpfile.js
[19:48:21] Starting 'excel-to-jsoncsv'...
[19:48:21] Finished 'excel-to-jsoncsv' after 126 ms
而且它显然奏效了。
我想创建一个用于 Gulp 中的 pipe() 调用的函数,它可以将 xlsx 文件转换为 json。
我在 gulp 3 中使用 NPM 包 'excel-as-json',但是 Gulp 4 迫使我真正理解它在做什么 ;-)
六个小时后,由于缺乏 js/async/streaming 知识,我无法让它工作,这激发了我的好奇心。
代码如下:
paths = {excel_sourcefiles: "./sourcefiles/*.xls*", excel_targetdir_local_csvjson: "./targetfiles_local/*.*"}
var replaceExt = require('replace-ext');
var PluginError = require('plugin-error')
var gulpFunction = require('gulp-function').gulpFunction // default ES6 export
var through = require("through2")
var convertExcel = require('excel-as-json').processFile;
var changed = require('gulp-changed');
var assign = Object.assign || require('object.assign');
var notify = require('gulp-notify');
var gulpIgnore = require('gulp-ignore');
var rename = require('gulp-rename');
gulp.task('excel-to-jsoncsv', function() {
return gulp.src(paths.excel_sourcefiles)
// .pipe(debug())
.pipe(gulpIgnore.exclude("*\~*")) // Ignore temporary files by Excel while xlsx is open
.pipe(gulpIgnore.exclude("*$*")) // Ignore temporary files by Excel while xlsx is open
.pipe(plumber({errorHandler: notify.onError('gulp-excel-to-jsoncsv error: <%= error.message %>')}))
.pipe(changed(paths.excel_targetdir_local_glob, { extension: '.csv' }))
.pipe(GulpConvertExcelToJson()) // This is where the magic should happen
.pipe(rename({ extname: '.csv' })) // Saving as .csv for SharePoint (does not allow .json files to be saved)
.pipe(gulp.dest(paths.excel_targetdir_local))
});
function GulpConvertExcelToJson() {
return through.obj(function(chunk, enc, callback) {
var self = this
if (chunk.isNull() || chunk.isDirectory()) {
callback() // Do not process directories
// return
}
if (chunk.isStream()) {
callback() // Do not process streams
// return
}
if (chunk.isBuffer()) {
convertExcel(chunk.path, null, null, // Converts file found at `chunk.path` and returns (err, `data`) its callback.
function(err, data) {
if (err) {
callback(new PluginError("Excel-as-json", err))
}
chunk.contents = new Buffer(JSON.stringify(data))
self.push(chunk)
callback()
// return
})
} else {
callback()
}
})
}
我(现在)知道还有其他 excel > json gulp 模块可以让我在不编写自己的模块的情况下解决这个问题,但我想了解我在这里应该做些什么。
返回的错误是'Did you forget to signal Async completion?',我尽量不这样做。但是,我尝试用 var self = this
修复错误 'this.push is not a function' 的尝试可能不是我应该做的。
查看 gulp-zip 之类的示例让我了解了不熟悉的符号,使我无法通过自学来解决这个问题。
总结:
- 我将如何在 through.obj 函数调用期间调用异步函数,其中块的内容使用(不受我控制的)异步函数更新,该函数仅向我提供回调(错误,数据)?
这个问题来自 excel
库。 The end
event should be finish
.
尝试失败
我做了以下操作,安装修改后的 excel.js:
rm -rf node_modules/excel
git clone https://github.com/bdbosman/excel.js node_modules/excel
cd node_modules/excel && npm i && cd ../..
这还不够,因为 excel-as-json
使用旧版本的 excel
。
要么您必须修改 excel-as-json
模块,使用 excel@1.0.0
(合并请求请求后),或者手动编辑 node_modules 中的文件。我这里介绍第二种方式。
临时解决方案
安装模块后编辑 excel
文件。
我用过:
sed -i "s/'end'/'finish'/g" node_modules/excel/excelParser.js
然后我运行:
$ gulp excel-to-jsoncsv
[19:48:21] Using gulpfile ~/so-question-gulp-async-function-call-xlsx/gulpfile.js
[19:48:21] Starting 'excel-to-jsoncsv'...
[19:48:21] Finished 'excel-to-jsoncsv' after 126 ms
而且它显然奏效了。