Kesalahan tegukan: Tugas-tugas berikut tidak selesai: Apakah Anda lupa memberi sinyal penyelesaian async?


212

Saya memiliki gulpfile.js berikut , yang saya jalankan melalui pesan baris perintah gulp :

var gulp = require('gulp');

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

Saya menerima pesan galat berikut:

[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?

Saya menggunakan tegukan 4 pada sistem Windows 10. Ini adalah keluaran darigulp --version :

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

1
Jika Anda di sini karena Anda punya masalah webpack-stream. Gunakan ini: github.com/shama/webpack-stream/issues/…
B3none

Jawaban:


447

Karena tugas Anda mungkin berisi kode asinkron, Anda harus memberi sinyal tegukan ketika tugas Anda telah selesai dijalankan (= "penyelesaian async").

Dalam Gulp 3.x Anda bisa pergi tanpa melakukan ini. Jika Anda tidak secara eksplisit mengisyaratkan penyelesaian async, hanya akan menganggap bahwa tugas Anda sinkron dan selesai segera setelah fungsi tugas Anda kembali. Gulp 4.x lebih ketat dalam hal ini. Anda harus secara eksplisit memberi sinyal penyelesaian tugas.

Anda dapat melakukannya dalam enam cara :

1. Kembalikan Stream

Ini sebenarnya bukan pilihan jika Anda hanya mencoba untuk mencetak sesuatu, tetapi itu mungkin mekanisme penyelesaian async yang paling sering digunakan karena Anda biasanya bekerja dengan aliran tegukan. Berikut adalah contoh (agak dibuat-buat) yang menunjukkannya untuk kasus penggunaan Anda:

var print = require('gulp-print');

gulp.task('message', function() {
  return gulp.src('package.json')
    .pipe(print(function() { return 'HTTP Server Started'; }));
});

Bagian penting di sini adalah returnpernyataan. Jika Anda tidak mengembalikan aliran, tegukan tidak dapat menentukan kapan aliran selesai.

2. Pengembalian a Promise

Ini adalah mekanisme yang jauh lebih pas untuk kasus penggunaan Anda. Perhatikan bahwa sebagian besar waktu Anda tidak perlu membuat Promiseobjek sendiri, biasanya akan disediakan oleh paket (misalnya paket yang sering digunakan delmengembalikan a Promise).

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

Menggunakan sintaks async / await ini dapat disederhanakan lebih jauh. Semua fungsi yang ditandai asyncsecara implisit mengembalikan Janji sehingga hal berikut juga berfungsi (jika versi node.js Anda mendukungnya ):

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

3. Panggil fungsi panggilan balik

Ini mungkin cara termudah untuk kasus penggunaan Anda: tegukan secara otomatis meneruskan fungsi panggilan balik ke tugas Anda sebagai argumen pertama. Panggil saja fungsi itu setelah selesai:

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

4. Mengembalikan a proses anak

Ini sebagian besar berguna jika Anda harus menjalankan alat baris perintah secara langsung karena tidak ada pembungkus node.js. Ini berfungsi untuk use case Anda tapi jelas saya tidak akan merekomendasikannya (terutama karena ini tidak terlalu portabel):

var spawn = require('child_process').spawn;

gulp.task('message', function() {
  return spawn('echo', ['HTTP', 'Server', 'Started'], { stdio: 'inherit' });
});

5. Kembalikan RxJSObservable .

Saya tidak pernah menggunakan mekanisme ini, tetapi jika Anda menggunakan RxJS mungkin berguna. Agak berlebihan jika Anda hanya ingin mencetak sesuatu:

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. Kembalikan EventEmitter

Seperti yang sebelumnya saya memasukkan ini untuk kelengkapan, tapi itu bukan sesuatu yang benar-benar akan Anda gunakan kecuali Anda sudah menggunakan EventEmitterkarena suatu alasan.

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
Setelah beberapa jam mencari di Google, saya menemukan contoh ini. Sangat membantu. Terima kasih!
paxtor

ini membantu saya, ths!
Anan

1
Saya sangat menghargai jawaban Anda. +1 waktu besar.
Konrad Viltersten

6
Saya menghargai jawaban Anda yang elegan dan informatif pada tanggal 17 November. Dan hari ini, pada hari Natal, aku menghargainya lagi. Ini adalah salah satu kasus ketika saya berharap saya dapat memberikan +2 ... Saya tidak percaya bahwa goolearching tidak menghapus tautan ini sebagai top # 1 ketika mencari " Tugas-tugas berikut tidak selesai " atau " Apakah Anda lupa memberi sinyal penyelesaian async? "...
Konrad Viltersten

"paket del yang sering digunakan mengembalikan Janji". Saya menggunakan del, bagaimana saya menulis kode teguk saya untuk mengambil keuntungan dari janji itu? (PS. Jawaban yang benar-benar menakjubkan! +1)
Daniel Tonon

84

Masalah dengan Gulp 4 .

Untuk mengatasi masalah ini, cobalah untuk mengubah kode Anda saat ini:

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

misalnya dalam hal ini:

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

atau ke dalam ini:

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

2
Panggilan yang hilang untuk dilakukan adalah masalah saya. Terima kasih atas jawaban Anda!
Marco Santarossa

1
Namun, perlu diketahui bahwa fungsi panah tidak memiliki cakupan yang terpisah.
JepZ

19

Ini berhasil!

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

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

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

2
ini jawaban terbaik
Văn Quyết

13

Saya mendapatkan kesalahan yang sama dengan mencoba menjalankan SASS / CSS build yang sangat sederhana .

Solusi saya (yang dapat mengatasi kesalahan yang sama atau serupa ini) adalah dengan menambahkan donesebagai parameter dalam fungsi tugas default, dan menyebutnya di akhir tugas default:

// 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.
})

Semoga ini membantu!


7
Senang melihat contoh dengan isi tugas yang sebenarnya
Jonathan

8

Anda perlu melakukan dua hal:

  1. Tambahkan asyncsebelum fungsi.
  2. Mulai fungsi Anda dengan return.

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

7

Saya tidak bisa mengklaim sangat berpengetahuan tentang hal ini tetapi saya memiliki masalah yang sama dan telah menyelesaikannya.

Ada cara 7 untuk mengatasi ini, dengan menggunakan fungsi async .

Tulis fungsi Anda tetapi tambahkan awalan async .

Dengan melakukan ini Gulp membungkus fungsi dengan janji, dan tugas akan berjalan tanpa kesalahan.

Contoh:

async function() {
  // do something
};

Sumber:

  1. Bagian terakhir pada halaman Gulp Completion Async : Menggunakan async / tunggu .

  2. Mozilla async berfungsi sebagai dokumen .


7

Ini merupakan masalah ketika bermigrasi dari tegukan versi 3 ke 4, Anda cukup menambahkan parameter yang dilakukan ke fungsi panggil kembali, lihat contoh

   const gulp = require("gulp")

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

5

Penanganan masalah: Kita perlu memanggil fungsi panggil balik (Tugas dan Anonim):

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

2

Ini dia: Tidak ada tugas yang sinkron .

Tidak ada tugas yang sinkron

Tugas sinkron tidak lagi didukung. Mereka sering menyebabkan kesalahan halus yang sulit di-debug, seperti lupa mengembalikan aliran Anda dari suatu tugas.

Ketika Anda melihat Did you forget to signal async completion?peringatan itu, tidak ada teknik yang disebutkan di atas yang digunakan. Anda harus menggunakan callback pertama-kesalahan atau mengembalikan aliran, janji, emitor acara, proses anak, atau diamati untuk menyelesaikan masalah.

Menggunakan async/await

Ketika tidak menggunakan salah satu opsi sebelumnya, Anda dapat mendefinisikan tugas Anda sebagai async function, yang membungkus tugas Anda dengan janji . Ini memungkinkan Anda untuk bekerja dengan janji secara sinkron menggunakan awaitdan menggunakan kode sinkron lainnya.

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

Pada dasarnya v3.X lebih sederhana tetapi v4.x ketat dalam hal tugas-tugas sinkron & asinkron ini.

The async / menunggu cukup sederhana & cara membantu untuk memahami alur kerja & masalah.

Gunakan pendekatan sederhana ini

const gulp = require('gulp')

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

1

Saya berjuang dengan ini baru-baru ini, dan menemukan cara yang tepat untuk membuat defaulttugas yang berjalan sasssaat sass:watchitu adalah:

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

1

Solusi saya: letakkan semuanya dengan async dan tunggu tegukan.

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

Anda perlu melakukan satu hal:

  • Tambahkan asyncsebelum fungsi.

const gulp = require('gulp');

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


0

Tambahkan selesai sebagai parameter dalam fungsi default. Itu akan berhasil.


0

Bagi mereka yang mencoba menggunakan tegukan untuk penyebaran lokal, kode berikut akan membantu

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

Bagi saya masalahnya berbeda: Angular-cli tidak diinstal (saya menginstal versi Node baru menggunakan NVM dan hanya lupa menginstal ulang angular cli)

Anda dapat memeriksa menjalankan "versi ng".

Jika Anda tidak memilikinya, jalankan saja "npm install -g @ angular / cli"

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.