Gulpエラー:次のタスクは完了しませんでした:非同期完了を通知するのを忘れていませんか?


212

コマンドラインのgulpメッセージを介して実行している次のgulpfile.jsがあります

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

回答:


448

タスクには非同期コードが含まれている可能性があるため、タスクの実行が終了したときにgulpに信号を送る必要があります(=「非同期完了」)。

Gulp 3.xでは、これを行わなくても回避できます。非同期完了を明示的に通知しなかった場合、gulpはタスクが同期であり、タスク関数が戻るとすぐに完了すると想定します。Gulp 4.xはこの点でより厳密です。タスクの完了明示的に通知する必要があります。

それには6つの方法があります

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

4
数時間グーグルで検索したところ、この例が見つかりました。非常に役立ちます。ありがとうございました!
paxtor

それは私にとって便利です。
Anan

1
回答ありがとうございます。+1の大きな時間。
Konrad Viltersten 2016年

6
11月17日のエレガントで有益な回答に感謝します。そして今日、クリスマスの日に、私はそれをもう一度感謝しています。私は私が賞2 ...私は「を探していたときにgoolearchingがトップ#1のように、このリンクを糞しないことを信じることができないことがしたいとき、これは例1で、次の作業が完了していない」または「あなたがしました非同期の完了を通知するのを忘れましたか? "...
Konrad Viltersten

「頻繁に使用されるdelパッケージはPromiseを返します」。私はdelを使用していますが、約束を利用するためにgulpコードをどのように記述しますか?(PS。絶対にすばらしい答え!+1)
ダニエルトノン

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
これが最善の答えです
ヴァンQuyết

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
実際のタスク内容の例を見るの
ジョナサン

8

次の2つのことを行う必要があります。

  1. asyncbefore関数を追加します。
  2. 関数をから始めますreturn

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

7

私はこれについて非常に精通していると主張することはできませんが、同じ問題を抱えて解決しました。

これを解決するには、非同期関数を使用する7番目の方法があります

関数を記述しますが、接頭辞asyncを追加します。

これを行うことにより、Gulpは関数をpromiseにラップし、タスクはエラーなしで実行されます。

例:

async function() {
  // do something
};

リソース:

  1. Gulpページの最後のセクション非同期完了async / awaitの使用

  2. Mozilla 非同期機能ドキュメント


7

これは、gulpバージョン3から4に移行する際の問題です。単に、コールバック関数に完了したパラメーターを追加できます。例を参照してください。

   const gulp = require("gulp")

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

5

回避策:コールバック関数(タスクと匿名)を呼び出す必要があります。

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

2

どうぞ: 同期タスクはありません

同期タスクなし

同期タスクはサポートされなくなりました。多くの場合、タスクからストリームを返すのを忘れるなど、デバッグが困難な微妙なミスが発生しました。

Did you forget to signal async completion?警告が表示された場合、上記の手法は使用されていません。問題を解決するには、エラーファーストコールバックを使用するか、ストリーム、プロミス、イベントエミッター、子プロセス、またはオブザーバブルを返す必要があります。

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

私の解決策:すべてを非同期で入れて、一瞬待ってください。

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;

1

あなたは一つのことをする必要があります:

  • asyncbefore関数を追加します。

const gulp = require('gulp');

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


0

デフォルト関数のパラメーターとしてdoneを追加します。それで十分です。


0

swaggerローカルデプロイメントに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を使用して新しいノードバージョンをインストールし、Angle CLIを再インストールするのを忘れた)

実行中の「ngバージョン」を確認できます。

持っていない場合は、「npm install -g @ angular / cli」を実行してください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.