繁体   English   中英

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

[英]Gulp error: The following tasks did not complete: Did you forget to signal async completion?

我有以下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的 output :

[14:15:15] CLI version 0.4.0
[14:15:15] Local version 4.0.0-alpha.2

由于您的任务可能包含异步代码,因此您必须在任务完成执行(=“异步完成”)时向 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包返回一个Promise )。

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

使用async/await语法可以进一步简化。 所有标记为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;
});

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

你需要做一件事:

  • 在函数之前添加async

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

我在尝试运行一个非常简单的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.
})

希望这有帮助!

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

   const gulp = require("gulp")

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

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

有第 7 种方法可以解决此问题,即使用async 函数

编写您的函数,但添加前缀async

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

示例:

async function() {
  // do something
};

资源:

  1. Gulp页面Async Completion 的最后一部分: 使用 async/await

  2. Mozilla 异步函数文档

你需要做两件事:

  1. 在函数之前添加async
  2. return启动你的函数。

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

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

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

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

async/await是理解工作流程和问题的非常简单且有用的方法。

使用这个简单的方法

const gulp = require('gulp')

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

给你: 没有同步任务

没有同步任务

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

当您看到Did you forget to signal async completion? 警告,上述技术均未使用。 您需要使用错误优先回调或返回流、promise、事件发射器、子进程或 observable 来解决问题。

使用async / await

当不使用任何前面的选项时,您可以将您的任务定义为async function ,它将您的任务包装在一个promise 中 这允许您使用await同步处理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;

我的解决方案:把所有东西都放在 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;

我解决了,这很简单,只需添加以下代码片段。

var gulp = require('gulp');

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

我最近在为此苦苦挣扎,并找到了创建运行sass然后sass:watchdefault任务的正确方法:

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

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

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

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

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

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

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

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

除了遵循保存 .scss 文件时输出的错误之外,我还通过遵循多个先前答案的说明解决了此问题。

简而言之:

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

  • 我把所有的函数都改成了 ASYNC 函数——见(B)

(A)对 gulp-sass 导入所做的更改:

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

(B)简单地将函数转换为 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();
})

我知道这个问题是 6 年前提出的,但可能你错过了 function 中的返回。我今天早上用 eslint 解决了这个问题,在我的工作目录中运行“gulp lint”后,它给了我同样的信息。

例子:

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

exports.lint = runLinter;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM