Ошибка 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
Ответы
Ответ 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 не сможет определить, когда поток закончился.
Это гораздо более подходящий механизм для вашего случая использования. Обратите внимание, что в большинстве случаев вам не нужно создавать объект 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();
});
Это в основном полезно, если вам нужно вызывать инструмент командной строки напрямую, потому что нет доступной оболочки node.js. Это работает для вашего случая использования, но, очевидно, я бы не рекомендовал его (тем более что он не очень переносимый):
var spawn = require('child_process').spawn;
gulp.task('message', function() {
return spawn('echo', ['HTTP', 'Server', 'Started'], { stdio: 'inherit' });
});
Я никогда не использовал этот механизм, но если вы используете 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;
});
Как и предыдущий, я включаю это для полноты картины, но на самом деле это не то, что вы собираетесь использовать, если по какой-то причине вы уже не используете 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
Вам нужно сделать две вещи;
- Добавить асинхронный перед функцией
-
Начните свою функцию с возврата
var gulp = require('gulp');
gulp.task('message', async function() {
return console.log("HTTP Server Started");
});