Gulp错误:以下任务未完成:您忘记发出异步完成信号了吗?

我有下面的gulpfile.js,我通过命令行杯的消息执行:

var gulp = require('gulp');


gulp.task('message', function() {
console.log("HTTP Server Started");
});

我得到以下错误消息:

[14:14:41] Using gulpfile ~\Documents\node\first\gulpfile.js
[14:14:41] Starting 'message'...
HTTP Server Started
[14:14:41] The following tasks did not complete: message
[14:14:41] Did you forget to signal async completion?

我在Windows 10系统上使用gulp 4。下面是gulp --version的输出:

[14:15:15] CLI version 0.4.0
[14:15:15] Local version 4.0.0-alpha.2
204830 次浏览

由于你的任务可能包含异步代码,你必须在任务执行完成时发出gulp信号(= "async completion")。

在Gulp 3。X,你可以不这样做。如果你没有显式地发出异步完成信号,gulp就会假设你的任务是同步的,只要你的任务函数返回,它就会完成。杯4。X在这方面更为严格。你必须显式地表示任务完成。

你可以在六个方面中这样做:

1. 返回

如果你只是想打印一些东西,这不是一个真正的选择,但它可能是最常用的异步完成机制,因为你通常使用gulp流。下面是一个(相当做作的)例子,为你的用例演示它:

var print = require('gulp-print');


gulp.task('message', function() {
return gulp.src('package.json')
.pipe(print(function() { return 'HTTP Server Started'; }));
});

这里重要的部分是return语句。如果不返回流,gulp无法确定流何时结束。

2. 返回Promise

这是一种更适合您的用例的机制。注意,大多数情况下你不需要自己创建Promise对象,它通常由包提供(例如,经常使用的del包返回Promise)。

gulp.task('message', function() {
return new Promise(function(resolve, reject) {
console.log("HTTP Server Started");
resolve();
});
});

使用异步/等待语法可以进一步简化。所有标记为async的函数都隐式返回Promise,因此以下也可以工作(如果您的Node.js版本支持):

gulp.task('message', async function() {
console.log("HTTP Server Started");
});

3.调用回调函数

对于您的用例来说,这可能是最简单的方法:gulp自动将一个回调函数作为第一个参数传递给任务。当你完成时,只需调用该函数:

gulp.task('message', function(done) {
console.log("HTTP Server Started");
done();
});

4. 返回子进程

如果你必须直接调用命令行工具,因为没有node.js包装器可用,这是非常有用的。它适用于你的用例,但显然我不推荐它(特别是因为它不是很可移植):

var spawn = require('child_process').spawn;


gulp.task('message', function() {
return spawn('echo', ['HTTP', 'Server', 'Started'], { stdio: 'inherit' });
});

5. 返回RxJS Observable

我从未使用过这种机制,但如果您正在使用RxJS,它可能会有用。如果你只是想打印一些东西,这有点过头了:

var of = require('rxjs').of;


gulp.task('message', function() {
var o = of('HTTP Server Started');
o.subscribe(function(msg) { console.log(msg); });
return o;
});

6. 返回EventEmitter

像前一个一样,为了完整性起见,我包含了这个,但它并不是你真正要使用的东西,除非你已经出于某种原因使用了EventEmitter

gulp.task('message3', function() {
var e = new EventEmitter();
e.on('msg', function(msg) { console.log(msg); });
setTimeout(() => { e.emit('msg', 'HTTP Server Started'); e.emit('finish'); });
return e;
});

解决方案:我们需要调用回调函数(任务和匿名):

function electronTask(callbackA)
{
return gulp.series(myFirstTask, mySeccondTask, (callbackB) =>
{
callbackA();
callbackB();
})();
}

Gulp 4的一个问题

为了解决这个问题,尝试改变您当前的代码:

gulp.task('simpleTaskName', function() {
// code...
});

举个例子:

gulp.task('simpleTaskName', async function() {
// code...
});

或者变成这样:

gulp.task('simpleTaskName', done => {
// code...
done();
});

这个工作!

最新更新日期为2021年2月18日,我在使用下面的老解决方案后发现了这个问题,然后我用下面的方法来解决下一个gulp版本。

文件:Package.json

...,
"devDependencies": {
"del": "^6.0.0",
"gulp": "^4.0.2",
},
...

文件:gulpfile.js

const {task} = require('gulp');
const del = require('del');


async function clean() {
console.log('processing ... clean');


return del([__dirname + '/dist']);
}


task(clean)
...

老版本

gulp.task('script', done => {
// ... code gulp.src( ... )
done();
});


gulp.task('css', done => {
// ... code gulp.src( ... )
done();
});


gulp.task('default', gulp.parallel(
'script',
'css'
)
);

我在尝试运行一个非常简单的SASS / CSS构建时得到了同样的错误。

我的解决方案(可以解决相同或类似的错误)只是在默认任务函数中添加done作为参数,并在默认任务结束时调用它:

// Sass configuration
var gulp = require('gulp');
var sass = require('gulp-sass');


gulp.task('sass', function () {
gulp.src('*.scss')
.pipe(sass())
.pipe(gulp.dest(function (f) {
return f.base;
}))
});


gulp.task('clean', function() {
})


gulp.task('watch', function() {
gulp.watch('*.scss', ['sass']);
})




gulp.task('default', function(done) { // <--- Insert `done` as a parameter here...
gulp.series('clean','sass', 'watch')
done(); // <--- ...and call it here.
})

希望这能有所帮助!

我不能说我在这方面很有知识,但我也遇到过同样的问题,并且已经解决了。

有第7种方法来解决这个问题,通过使用异步函数

编写函数,但要加上前缀< em >异步< / em >

通过这样做,Gulp将函数包装在承诺中,任务将正常运行。

例子:

async function() {
// do something
};

< em >资源:< / em >

  1. Gulp page Async Completion: Using Async /await

  2. Mozilla async functions docs

在默认函数中添加done作为参数。这样就行了。

对于那些试图使用gulp进行本地部署的人,下面的代码将有所帮助

var gulp = require("gulp");
var yaml = require("js-yaml");
var path = require("path");
var fs = require("fs");


//Converts yaml to json
gulp.task("swagger", done => {
var doc = yaml.safeLoad(fs.readFileSync(path.join(__dirname,"api/swagger/swagger.yaml")));
fs.writeFileSync(
path.join(__dirname,"../yourjsonfile.json"),
JSON.stringify(doc, null, " ")
);
done();
});


//Watches for changes
gulp.task('watch', function() {
gulp.watch('api/swagger/swagger.yaml', gulp.series('swagger'));
});

给你: 无同步任务

无同步任务

不再支持同步任务。它们通常会导致难以调试的细微错误,比如忘记从任务中返回流。

当你看到Did you forget to signal async completion?警告时,上面提到的技术都没有被使用。您需要使用错误优先回调或返回流、承诺、事件发射器、子进程或可观察对象来解决该问题。

使用async / await

当不使用任何前面的选项时,可以将任务定义为async function,它将任务包装在承诺中。这允许你使用await和其他同步代码同步地使用promise。

const fs = require('fs');


async function asyncAwaitTask() {
const { version } = fs.readFileSync('package.json');
console.log(version);
await Promise.resolve('some result');
}


exports.default = asyncAwaitTask;

你需要做两件事:

  1. 在函数前添加async
  2. 使用return启动函数。

    var gulp = require('gulp');
    
    
    gulp.task('message', async function() {
    return console.log("HTTP Server Started");
    });
    

基本上v3。X更简单,但是v4。X在这些同步&异步任务。

异步/等待非常简单&有助于理解工作流程问题。

使用这个简单的方法

const gulp = require('gulp')


gulp.task('message',async function(){
return console.log('Gulp is running...')
})

我最近一直在努力解决这个问题,并找到了创建运行sassdefault任务的正确方法,然后sass:watch是:

gulp.task('default', gulp.series('sass', 'sass:watch'));

当从gulp版本3迁移到4时,这是一个问题,你可以简单地添加一个参数到回调函数,参见示例。

   const gulp = require("gulp")


gulp.task("message", function(done) {
console.log("Gulp is running...")
done()
});

我的解决方案:把所有东西都放在async中,然后等待gulp。

async function min_css() {
return await gulp
.src(cssFiles, { base: "." })
.pipe(concat(cssOutput))
.pipe(cssmin())
.pipe(gulp.dest("."));
}


async function min_js() {
return await gulp
.src(jsFiles, { base: "." })
.pipe(concat(jsOutput))
.pipe(uglify())
.pipe(gulp.dest("."));
}


const min = async () => await gulp.series(min_css, min_js);


exports.min = min;


对我来说,问题是不同的:没有安装Angular-cli(我使用NVM安装了一个新的Node版本,只是忘记重新安装angular cli)

你可以检查运行“ng version”。

如果你没有,运行"npm install -g @angular/cli"

你需要做一件事:

  • 在函数前添加async
const gulp = require('gulp');


gulp.task('message', async function() {
console.log("Gulp is running...");
});

解决方法很简单,,但我概述了我所做的更改,我得到的错误,我的gulpfile之前和之后,和包的版本-因此使它看起来很长。

除了遵循保存.scss文件时输出的错误外,我还通过遵循前面多个答案的方向解决了这个问题。

简而言之:

  • 我改变了gulp-sass的导入方式-参见(一)

  • 我将所有函数都更改为ASYNC函数-参见(B)

(一) gulp-sass导入的更改:

  • : var sass = require('gulp-sass)
  • 后:var sass = require('gulp-sass')(require('sass'));

简单地将函数转换为ASYNC -

我的gulpfile看起来像以前:

'use strict';
 

// dependencies
var gulp = require('gulp');
var sass = require('gulp-sass');
var minifyCSS = require('gulp-clean-css');
var uglify = require('gulp-uglify');
var rename = require('gulp-rename');
var changed = require('gulp-changed');
 

var SCSS_SRC = './src/Assets/scss/**/*.scss';
var SCSS_DEST = './src/Assets/css';
 

function compile_scss() {
return gulp.src(SCSS_SRC)
.pipe(sass().on('error', sass.logError))
.pipe(minifyCSS())
.pipe(rename({ suffix: '.min' }))
.pipe(changed(SCSS_DEST))
.pipe(gulp.dest(SCSS_DEST));
}
 

 

function watch_scss() {
gulp.watch(SCSS_SRC, compile_scss);
}


gulp.task('default', watch_scss); //Run tasks
 

exports.compile_scss = compile_scss;
exports.watch_scss = watch_scss;

我的gulpfile看起来像:

'use strict';
 

// dependencies
var gulp = require('gulp');
//var sass = require('gulp-sass');
var sass = require('gulp-sass')(require('sass'));
var minifyCSS = require('gulp-clean-css');
var uglify = require('gulp-uglify');
var rename = require('gulp-rename');
var changed = require('gulp-changed');


var SCSS_SRC = './src/Assets/scss/**/*.scss';
var SCSS_DEST = './src/Assets/css';
 

async function compile_scss() {
return gulp.src(SCSS_SRC)
.pipe(sass().on('error', sass.logError))
.pipe(minifyCSS())
.pipe(rename({ suffix: '.min' }))
.pipe(changed(SCSS_DEST))
.pipe(gulp.dest(SCSS_DEST));
}
 

async function watch_scss() {
gulp.watch(SCSS_SRC, compile_scss);
}
 

gulp.task('default', watch_scss); // Run tasks
 

exports.compile_scss = compile_scss;
exports.watch_scss = watch_scss;

包版本:

"gulp": "^4.0.2",
"gulp-changed": "^4.0.3",
"gulp-rename": "^2.0.0",
"gulp-uglify": "^3.0.2",
"gulp-clean-css": "^4.3.0",
"gulp-sass": "^5.0.0",
"sass": "^1.38.0"

我得到的错误:

Error in plugin "gulp-sass"
Message:


gulp-sass 5 does not have a default Sass compiler; please set one yourself.
Both the `sass` and `node-sass` packages are permitted.
For example, in your gulpfile:


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


[14:00:37] The following tasks did not complete: default, compile_scss
[14:00:37] Did you forget to signal async completion?

在gulp版本4及更高版本中,要求所有gulp任务都告诉gulp任务将在何处结束。为此,我们调用一个函数,该函数作为任务函数中的第一个参数传递

var gulp = require('gulp');
gulp.task('first_task', function(callback) {
console.log('My First Task');
callback();
})

我解决了这个问题,这很简单,只需添加下面的代码片段。

var gulp = require('gulp');


gulp.task('message', async function() {
console.log("HTTP Server Started");
});
我知道这个问题在6年前就出现了,但可能你在函数中错过了返回。 我今天早上用eslint修复了这个问题,它在运行“gulp lint”后给了我同样的消息。

例子:

function runLinter(callback)
{
return src(['**/*.js', '!node_modules/**'])
.pipe(eslint())
.on('end', ()=>
{
callback();
});
}


exports.lint = runLinter;