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

Joh*_*han 165 gulp

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

var gulp = require('gulp');

gulp.task('message', function() {
  console.log("HTTP Server Started");
});
Run Code Online (Sandbox Code Playgroud)

我收到以下错误消息:

[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?
Run Code Online (Sandbox Code Playgroud)

我在Windows 10系统上使用gulp 4.这是gulp --version的输出:

[14:15:15] CLI version 0.4.0
[14:15:15] Local version 4.0.0-alpha.2
Run Code Online (Sandbox Code Playgroud)

Sve*_*ung 384

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

在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'; }));
});
Run Code Online (Sandbox Code Playgroud)

这里的重要部分是return声明.如果您不返回流,gulp无法确定流何时完成.

2.返回一个 Promise

这是一个更适合您的用例的机制.请注意,大多数情况下您不必Promise自己创建对象,它通常由包提供(例如,常用del包返回a Promise).

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

使用async/await语法可以进一步简化.标记的所有函数都async隐式返回Promise,因此以下也适用(如果您的node.js版本支持它):

gulp.task('message', async function() {
  console.log("HTTP Server Started");
});
Run Code Online (Sandbox Code Playgroud)

3.调用回调函数

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

gulp.task('message', function(done) {
  console.log("HTTP Server Started");
  done();
});
Run Code Online (Sandbox Code Playgroud)

4.返回子进程

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

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

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

5.返回RxJSObservable.

我从来没有使用过这种机制,但是如果你使用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;
});
Run Code Online (Sandbox Code Playgroud)

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;
});
Run Code Online (Sandbox Code Playgroud)

  • 我赞赏你在11月17日的优雅和翔实的答案.今天,在圣诞节那天,我再次欣赏它.这是我希望我可以奖励+2的情况之一...我无法相信goolearching在查找"*以下任务未完成*"或"*您是否忘记发信号异步完成?*"...... (6认同)
  • 经过几个小时的谷歌搜索,我找到了这个例子.很有帮助.谢谢! (4认同)
  • 我非常感谢你的回答。+1 大时代。 (2认同)

sim*_*eco 41

与咕嘟咕嘟4个问题 -你需要明确的信号,任务完成每个功能.

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

gulp.task('simpleTaskName', function() {
  // code...
});
Run Code Online (Sandbox Code Playgroud)

比如这个:

gulp.task('simpleTaskName', async function() {
  // code...
});
Run Code Online (Sandbox Code Playgroud)

  • async function() 最简单、最快的解决方案。+1 (3认同)
  • 缺少对 done 的调用是我的问题。谢谢您的回答! (2认同)

Kha*_*aen 18

这工作了!

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

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

gulp.task('default', gulp.parallel(
        'script',
        'css'
  )
);
Run Code Online (Sandbox Code Playgroud)

  • 这是最好的答案 (2认同)
  • 将旧项目升级到 Gulp 4.x 后,这解决了我的问题。谢谢! (2认同)
  • 太棒了,这个答案节省了我很多时间!谢谢@KhachornchitSongsaen 这应该被接受的答案! (2认同)

小智 16

你需要做一件事:

  • 添加async之前的功能。

const gulp = require('gulp');

gulp.task('message', async function() {
    console.log("Gulp is running...");
});
Run Code Online (Sandbox Code Playgroud)


小智 11

我在尝试运行非常简单的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.
})
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助!

  • 很高兴看到包含实际任务内容的示例 (6认同)
  • 如果您在 gulp.series() 之后立即调用 done(),那么它看起来不会等待一系列任务完成。也许该进程在退出之前会等待,但如果您尝试将其组合成更大的任务结构,这似乎不会很好地工作。 (3认同)

小智 11

这是从 gulp 版本 3 迁移到 4 时的一个问题,您只需在回调函数中添加一个参数 done ,请参见示例,

   const gulp = require("gulp")

    gulp.task("message", function(done) {
      console.log("Gulp is running...")
      done()
    });
Run Code Online (Sandbox Code Playgroud)


小智 7

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

function electronTask(callbackA)
{
    return gulp.series(myFirstTask, mySeccondTask, (callbackB) =>
    {
        callbackA();
        callbackB();
    })();    
}
Run Code Online (Sandbox Code Playgroud)


Jon*_*nny 7

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

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

编写函数,但添加前缀async

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

例:

async function() {
  // do something
};
Run Code Online (Sandbox Code Playgroud)

资源:

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

  2. Mozilla 异步函数docs


Maj*_*ali 7

您需要做两件事:

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

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


Nav*_*dav 5

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

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

使用这个简单的方法

const gulp = require('gulp')

gulp.task('message',async function(){
return console.log('Gulp is running...')
})
Run Code Online (Sandbox Code Playgroud)