簡體   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