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

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

23 ответа

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

2. Вернуть Promise

Это гораздо более подходящий механизм для вашего случая использования. Обратите внимание, что большую часть времени вам не придется создавать Promise возражать самому, обычно он предоставляется пакетом (например, часто используемым del пакет возвращает Promise).

gulp.task('message', function() { 
  return new Promise(function(resolve, reject) {
    console.log("HTTP Server Started");
    resolve();
  });
});

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 Observable = require('rx').Observable;

gulp.task('message', function() {
  var o = Observable.just('HTTP Server Started');
  o.subscribe(function(str) {
    console.log(str);
  });
  return o;
});

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

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

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

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

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

Вам нужно сделать одно:

  • добавлять async перед функцией.

const gulp = require('gulp');

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

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

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

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

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

Я получал ту же ошибку, пытаясь запустить очень простую сборку 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, просто вы можете добавить параметр, сделанный для функции обратного вызова, см. Пример,

   const gulp = require("gulp")

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

Я не могу утверждать, что я очень хорошо осведомлен в этом, но у меня была та же проблема, и я решил ее. Есть 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

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

  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 строг в этих средствах синхронных и асинхронных задач.

Асинхронный / Await довольно простой и удобный способ, чтобы понять рабочий процесс & вопрос.

Используйте этот простой подход

const gulp = require('gulp')

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

Вот и все: никаких синхронных задач.

Нет синхронных задач

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

Когда вы видите Did you forget to signal async completion?предупреждение, ни один из упомянутых выше методов не использовался. Для решения проблемы вам нужно будет использовать обратный вызов error-first или вернуть поток, обещание, эмиттер событий, дочерний процесс или наблюдаемое.

С помощью async/await

Если вы не используете ни один из предыдущих вариантов, вы можете определить свою задачу как async function, который превращает вашу задачу в обещание. Это позволяет вам работать с обещаниями синхронно, используя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;

Я решил это, это довольно просто, просто добавьте приведенный ниже фрагмент кода.

      var gulp = require('gulp');

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

Мое решение: поставить все с помощью async и ждать глотка.

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;

Решение простое, но я описываю внесенные мной изменения, полученную ошибку, мой файл 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?

Недавно я боролся с этим и нашел правильный способ создать default задача, которая выполняется sass тогда sass:watch был:

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

Итак, я получил ту же ошибку с Gulp 4, но решение было другим. У меня была ошибка: «Вы забыли сигнализировать о завершении асинхронности?» но перед ошибкой также говорится: «gulp-sass больше не имеет компилятора Sass по умолчанию; пожалуйста, установите его самостоятельно». Сначала я полностью пропустил эту часть. Итак, у меня было это в gulfile.js:

      const sass = require('gulp-sass')

Это должно быть изменено на:

      const sass = require('gulp-sass')(require('sass'));

Теперь это работает.

В gulp версии 4 и выше требуется, чтобы все задачи gulp сообщали Gulp, где задача завершится. Мы делаем это, вызывая функцию, которая передается в качестве первого аргумента нашей функции задачи.

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

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

Для меня проблема была в другом: Angular-cli не был установлен (я установил новую версию Node с помощью NVM и просто забыл переустановить angularcli)

Вы можете проверить запущенную "версию ng".

Если у вас его нет, просто запустите "npminstall -g @angular/cli"

Простое добавление async сработало для меня. Спасибо!

Я знаю, что проблема была представлена ​​6 лет назад, но, вероятно, вы пропустили возврат в своей функции. Сегодня утром я исправил эту проблему с помощью eslint, который выдал мне то же сообщение после запуска «gulp lint» в моем рабочем каталоге.

Пример:

      function runLinter(callback)
{
  return src(['**/*.js', '!node_modules/**'])
    .pipe(eslint())
    .on('end', ()=>
    {
        callback();
    });
}

exports.lint = runLinter;

Просто добавьте gulp перед функцией в файле gulp.js. надеюсь, что это может решить. Вы можете увидеть раздел async/await в документации gulp -> https://gulpjs.com/docs/en/getting-started/async-completion/

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