Подтвердить что ты не робот

Ошибка Gulp: следующие задачи не были выполнены: вы забыли обработать асинхронное завершение?

У меня есть следующий 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?

Я использую gulp 4 в системе Windows 10. Вот результат из gulp --version:

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

Ответ 1

Поскольку ваша задача может содержать асинхронный код, вы должны сигнализировать 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;
});

Ответ 2

Проблема с Gulp 4 - вам нужно явно сигнализировать о завершении задачи для каждой функции.

Для решения этой проблемы попробуйте изменить свой текущий код:

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

например в это:

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

Ответ 3

Это сработало!

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

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

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

Ответ 4

Я получал ту же ошибку, пытаясь запустить очень простую сборку 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
})

Надеюсь это поможет!

Ответ 5

Обходной путь: нам нужно вызвать функции обратного вызова (Task и Anonymous):

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

Ответ 6

Я не могу утверждать, что я очень хорошо осведомлен в этом, но у меня была та же проблема, и я решил ее. Есть 7-й способ решить эту проблему, используя асинхронную функцию.

Напишите свою функцию, но добавьте префикс async.
Делая это, Gulp оборачивает функцию в обещание, и задача будет выполняться без ошибок.

Пример:

async function() {
  // do something
};

Ресурсы:

Последний раздел на странице gulp "Асинхронное завершение" здесь, "Использование 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

Ответ 7

этот работал на меня

    'gulp.task('html', async function() {
     console.log("Now gulp can run");
     });'

Напечатайте "gulp html" в терминале, и это работает. У меня есть узел v11.14.0 и установлен gulp v4.0.0

спасибо @Свен Шёнунг

Ответ 8

Добавить сделано в качестве параметра в функции по умолчанию. Что будет делать.

Ответ 9

Для тех, кто пытается использовать 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'));  
});

Ответ 10

Ну вот:

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

Нет синхронных задач Синхронные задачи больше не поддерживаются. Они часто приводили к тонким ошибкам, которые трудно было отладить, например, забывать возвращать потоки из задачи.

Когда вы видите "Вы забыли сообщить о завершении асинхронного?" предупреждение, ни один из методов, упомянутых выше, не использовался. Вам нужно будет использовать обратный вызов с ошибкой сначала или вернуть поток, обещание, источник событий, дочерний процесс или наблюдаемый для решения проблемы.

Использование async/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;

Ответ 11

Вам нужно сделать две вещи;

  1. Добавить асинхронный перед функцией
  2. Начните свою функцию с возврата

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