web-dev-qa-db-ja.com

Gulp error:次のタスクは完了しませんでした。非同期完了の通知を忘れましたか?

私は以下のgulpfile.jsを持っています、それは私がコマンドライン "gulp message"を通して実行しています:

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
138
user1738579

タスクに非同期コードが含まれている可能性があるので、タスクの実行が終了したときにgulpに通知する必要があります(= "async completion")。

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 packageは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;
});
313
Sven Schoenung

Gulp 4に関する問題 - 明示的にsignalタスク完了各関数

この問題を解決するために、現在のコードを変更してみてください。

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

例えばこれに:

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

これはうまくいった!

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

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

gulp.task('default', gulp.parallel(
        'script',
        'css'
  )
);
10

私は非常に単純な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
})

お役に立てれば!

4
jus-hau-wee

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

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

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

  1. 関数の前に非同期を追加
  2. Returnで関数を開始します

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

私はこれについて非常に精通していると主張することはできませんが、私は同じ問題を抱えていてそれを解決しました。 非同期関数を使用して、これを解決する7番目の方法があります。

あなたの関数を書きなさい、しかし接頭辞asyncを加えなさい。
これを行うことによって、Gulpは約束の中に関数をラップし、タスクはエラーなしで実行されます。

例:

async function() {
  // do something
};

参考文献:

gulpページの最後のセクション、 'async completion'、ここでは 'Using async/await':

https://gulpjs.com/docs/en/getting-started/async-completion

Mozilla非同期関数のドキュメントはこちら:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function

3
Jonny

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

0
bmayur

より簡単なローカル展開に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
hellowahab

どうぞ:

https://gulpjs.com/docs/en/getting-started/async-completion#no-synchronous-tasks

同期タスクはありません同期タスクはサポートされなくなりました。それらは、タスクからストリームを返すのを忘れるなど、デバッグするのが難しい微妙なミスをしばしば引き起こしました。

「非同期の完了を通知するのを忘れましたか?」警告、上記の手法はいずれも使用されていません。問題を解決するには、エラーファーストコールバックを使用するか、ストリーム、Promise、イベントエミッター、子プロセス、またはObservableを返す必要があります。

Async/awaitの使用上記のオプションを使用しない場合、タスクをasync関数として定義できます。これは、タスクをプロミスでラップします。これにより、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;
0
Lloyd Apter