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


211

我有以下gulpfile.js,我正在通过命令行gulp消息执行:

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

1
如果您在这里是因为遇到问题webpack-stream。使用它:github.com/shama/webpack-stream/issues/…–
B3none

Answers:


448

由于您的任务可能包含异步代码,因此您必须在任务完成执行时发出gulp信号(=“异步完成”)。

在Gulp 3.x中,您可以不这样做而逃脱。如果您未明确表示异步完成信号,那么gulp只会假设您的任务是同步的,并且一旦任务函数返回就完成了。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包返回a 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.返回一个RxJSObservable

我从未使用过这种机制,但是如果您使用的是RxJS,它可能会很有用。如果您只想打印一些内容,那是一种矫kill过正:

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;
});

4
经过几个小时的谷歌搜索,我找到了这个例子。很有帮助。谢谢!
paxtor '16

这对我有帮助!
阿南

1
非常感谢您的回答。+1大时间。
康拉德·维特尔斯滕

6
感谢您在11月17日提出的优雅而有益的回答。今天,在圣诞节那天,我再次感激不尽。这是其中一个案件时,我希望我能获奖+2 ...我不能相信goolearching不poops此链接为顶部#1寻找时,“ 下面的任务没有完成 ”或“ 你有没有忘记发出异步完成信号了吗?
Konrad Viltersten

“经常使用的del包返回Promise”。我正在使用del,但是我如何编写gulp代码以利用Promise?(PS。绝对惊人的答案!+1)
Daniel Tonon

84

Gulp的问题4

为解决此问题,请尝试更改当前代码:

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

例如:

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

或成这样:

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

2
遗漏的待办事项是我的问题。谢谢您的回答!
Marco Santarossa,

1
但是,请注意,箭头功能没有单独的范围。
JepZ

19

这工作了!

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

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

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

2
这是最好的答案
范奎特

13

我在运行一个非常简单的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
很高兴看到包含实际任务内容的示例
乔纳森(Jonathan),

8

您需要做两件事:

  1. async在函数之前添加。
  2. 从开始功能return

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

7

我不能声称自己对此非常了解,但是我遇到了同样的问题并已解决。

通过使用async函数,可以解决第七种问题。

编写函数,但添加前缀async

通过这样做,Gulp将函数包装在一个Promise中,该任务将无错误运行。

例:

async function() {
  // do something
};

资源:

  1. Gulp页面上的最后一部分异步完成使用async / await

  2. Mozilla 异步函数docs


7

从gulp第3版迁移到第4版时,这是一个问题。只需将完成的参数添加到回调函数,请参见示例,

   const gulp = require("gulp")

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

5

解决方法:我们需要调用回调函数(Task和Anonymous):

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

2

在这里,您可以: 没有同步任务

没有同步任务

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

当您看到Did you forget to signal async completion?警告时,没有使用上述任何技术。您将需要使用错误优先回调或返回流,promise,事件发射器,子进程或可观察对象来解决问题。

使用async/await

如果不使用上述任何选项,则可以将任务定义为async function,将任务包装在promise中。这使您可以同步使用承诺await并使用其他同步代码。

const fs = require('fs');

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

exports.default = asyncAwaitTask;

2

基本上,v3.X较为简单,但v4.x在同步和异步任务的这些方式上非常严格。

异步/的await是非常简单的和有益的方式了解工作流程和问题。

使用这种简单的方法

const gulp = require('gulp')

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

1

我最近在为此苦苦挣扎,发现创建default运行sass当时的任务的正确方法sass:watch是:

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

1

我的解决方案:将所有内容放入异步并等待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;

0

在默认功能中,将完成添加为参数。这样就可以了。


0

对于那些试图使用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'));  
});

0

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

您可以检查正在运行的“ ng版本”。

如果没有,只需运行“ npm install -g @ angular / cli”


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.