【问题标题】:Gulp error: The following tasks did not complete: Did you forget to signal async completion?Gulp 错误:以下任务未完成:您是否忘记发出异步完成信号?
【发布时间】:2016-08-22 05:26:21
【问题描述】:

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

【问题讨论】:

标签: gulp


【解决方案1】:

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

在 Gulp 3.x 中,您无需这样做就可以逃脱。如果您没有明确表示异步完成,gulp 只会假设您的任务是同步的,并且一旦您的任务函数返回它就完成了。 Gulp 4.x 在这方面更加严格。您必须明确表示任务完成。

你可以在six ways

1。返回Stream

如果您只是想打印一些东西,这并不是一个真正的选择,但它可能是最常用的异步完成机制,因为您通常使用 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 version supports it):

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

3。调用回调函数

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

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

4。返回child process

如果您必须直接调用命令行工具,这非常有用,因为没有可用的 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;
});

【讨论】:

  • 经过几个小时的谷歌搜索,我找到了这个例子。非常有帮助。谢谢!
  • 这对我很有帮助!
  • 非常感谢您的回答。 +1 大时代。
  • 感谢您在 11 月 17 日优雅而翔实的回答。今天,在圣诞节那天,我再次感谢它。这是我希望我能奖励 +2 的情况之一......我不敢相信在寻找“以下任务未完成 i>”或“您是否忘记发出异步完成信号?”...
  • 谢谢你!那个单一的回报解决了我的问题,我在重用旧的 gulp3 代码并更新到 gulp 4 时寻找了很长一段时间
【解决方案2】:

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

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

【讨论】:

    【解决方案3】:

    Gulp 4 的问题

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

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

    例如变成这样:

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

    或者进入这个:

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

    【讨论】:

    • 缺少对 done 的调用是我的问题。谢谢你的回答!
    • 但是,请注意箭头函数没有单独的作用域。
    • async function() 最简单、最快的解决方案。 +1
    【解决方案4】:

    成功了!

    最后更新于 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'
      )
    );
    

    【讨论】:

    • 这是最佳答案
    • 将旧项目升级到 Gulp 4.x 后,这解决了我的问题。谢谢!
    • @Anton,我在发现一个新问题后更新了上述内容,并于 2021 年 2 月 18 日修复了它。
    • 太好了,这个答案节省了我很多时间!!!谢谢@KhachornchitSongsaen,这应该被接受!
    【解决方案5】:

    我在尝试运行非常简单的 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.series() 之后立即调用 done(),这看起来不会等待一系列任务完成。也许进程在退出之前会等待,但如果您尝试将其组合成更大的任务结构,这似乎效果不佳。
    【解决方案6】:

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

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

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

    通过这样做,Gulp 将函数包装在一个 Promise 中,任务将运行而不会出错。

    示例:

    async function() {
      // do something
    };
    

    资源:

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

    2. Mozilla async functions docs

    【讨论】:

      【解决方案7】:

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

      【讨论】:

        【解决方案8】:

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

        【讨论】:

          【解决方案9】:

          给你:No synchronous tasks

          无同步任务

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

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

          使用async/await

          当不使用上述任何选项时,您可以将您的任务定义为 async function,它将您的任务包装在 promise 中。这允许您使用 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;
          

          【讨论】:

            【解决方案10】:

            你需要做两件事:

            1. 在函数前添加async
            2. return 开始您的函数。

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

            【讨论】:

              【解决方案11】:

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

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

              使用这种简单的方法

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

              【讨论】:

                【解决方案12】:

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

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

                【讨论】:

                  【解决方案13】:

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

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

                  【讨论】:

                    【解决方案14】:

                    我的解决方案:将所有内容都使用 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;
                    
                    

                    【讨论】:

                    • 我不认为.pipe 是可以等待的。
                    【解决方案15】:

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

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

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

                    【讨论】:

                      【解决方案16】:

                      你需要做一件事:

                      • 在函数前添加async

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

                      【讨论】:

                      • 简单地添加异步对我有用,节省了我的一天。谢谢!
                      【解决方案17】:

                      解决方案很简单,但我概述了我所做的更改、我遇到的错误、我之前和之后的 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?
                      

                      【讨论】:

                        【解决方案18】:

                        在 gulp 版本 4 及更高版本中,要求所有 gulp 任务都告诉 Gulp 任务将在哪里结束。我们通过调用作为任务函数的第一个参数传递的函数来做到这一点

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

                        【讨论】:

                          猜你喜欢
                          • 1970-01-01
                          • 1970-01-01
                          • 1970-01-01
                          • 1970-01-01
                          • 1970-01-01
                          • 1970-01-01
                          • 2021-10-26
                          • 2018-05-10
                          • 1970-01-01
                          相关资源
                          最近更新 更多