node.js - Hur hanterar man på rätt sätt Gulp's Task-funktion i NodeJS API?
För närvarande känner jag bara till en fungerande metod för att köra Gulp-uppgiften utan gulpfile och CLI:
import Gulp from "gulp";
const TASK_NAME: string = "EXAMPLE_TASK";
Gulp.task(TASK_NAME, Gulp.parallel([
// ... imported task fuctions ...
]);
Gulp.task(TASK_NAME)(
(error?: Error | null): void => { if (isNeitherUndefinedNorNull(error)) { console.error(error); } }
);
Det är inte ämnet för frågan; jag förklarade bara vad jag gör och varför min kod är sådan som den är, men om du vet en bättre metod för att köra Gulp-uppgifter utan gulpfile och CLI, vänligen meddela mig.
Nu om ämnet. Fram till nyligen har den sista delen av koden (Gulp.task(TASK_NAME)(/* ... */)) inte avvisats av regeln no-floating-promises i typescript-eslint. Men efter den senaste uppdateringen av @types/gulp (eller typescript-eslint - nu är det svårt att undersöka vilken) varnar typescript-eslint mig:
Löften måste hanteras på lämpligt sätt eller uttryckligen markeras som ignorerade med
void-operatorn
där. Jag vet att det inte är ett falskt larm. Ibland bryts mina Gulp-uppgifter med unhandled promise rejection, men det var inte uppenbart var löftet var. Nu hade jag ledtråden, men det är fortfarande oklart.
Jag utforskade det:
Gulp.task()returneradeUndertaker.TaskFunctionWrappedTaskFunctionWrappedutökarTaskFunctionBaseTaskFunctionBaseär(done: TaskCallback): ReturnType<AsyncTask>;AsyncTaskär:
export type AsyncTask<R = any> =
((done: VoidCallback) => void)
| ((done: Callback<R>) => void)
| (() => ChildProcess | EventEmitter | Observable<R> | PromiseLike<R> | Stream);
Enligt dokumentationen måste task-funktionen returnera ChildProcess, EventEmitter, Observable, Promise eller Stream. Men hur hanterar man det? Gult.task()() är inte thenable:
Felmeddelande:
TS2339: Egenskapen 'catch' finns inte på typen 'void | EventEmitter | ChildProcess | Stream | Observable | PromiseLike'.
Uppdatering: försök @TheBumpaster lösning
Tyvärr säger @typescript/eslint fortfarande till mig "Promises måste hanteras på ett lämpligt sätt eller uttryckligen markeras som ignorerade med void-operatorn" på raden Gulp.task(ProjectBuilder.GULP_TASK_NAME).
const task: Promise<void> = new Promise<void>((resolve: () => void, reject: (error: Error) => void): void => {
console.log("checkpoint1");
Gulp.task(ProjectBuilder.GULP_TASK_NAME)(
(error?: Error | null): void => {
if (isNeitherUndefinedNorNull(error)) {
console.log("checkpoint2-A");
reject(error);
} else {
console.log("checkpoint2-B");
resolve();
}
}
);
});
task.catch((error: Error): void => { console.error(error); });
Jag höjer medvetet felet i några av gulp-pluginsen. Projektbyggaren når "checkpoint1" men varken "checkpoint2-A" eller "checkpoint2-B". Utmatningen är:
D:\XXX\node_modules\async-done\index.js:18
throw err;
^
Error [ERR_UNHANDLED_ERROR]: Unhandled error. ({
uid: 0,
name: '<anonymous>',
branch: false,
error: AssertionError [ERR_ASSERTION]:
Kanske indikerar det indirekt att @typescript/eslint:s skrikande inte bara är tomma ord...
Svar #1
Du borde ha varit medveten om att hantering av löften krävs för 'catch'-funktionen.
Enligt https://gulpjs.com/docs/en/getting-started/async-completion/
Gulp.Task(ProjectBuilder.GLUP_TASK_NAME)( (error) => { if ( error ) {
throw new Error(error); } // this is already executed
}
const task = new Promise( (resolve, reject ) => {
Gulp.Task(ProjectBuilder.GLUP_TASK_NAME)( (error) => { if ( error ) { reject(error) } resolve() }
});
task().then().catch(e => console.error(e))
Uppdatering om kommentar:
Kanske kan detta exempel hjälpa dig att visa vad jag menade med min kod ovan.
const gulp = require("gulp")
const taskName = "task-name"
// Example callback
gulp.task(taskName, (error) => {
if (error) {
console.error(error);
}
// It's already executed here
console.log(taskName)
});
// Example Promise object
const Task = new Promise( (resolve, reject) => {
gulp.task(taskName, (error) => {
if (error) {
reject(error)
}
resolve(taskName)
});
});
Task.then(console.log).catch(console.error)
// Example Promise function
const performTask = (_taskName) => {
return new Promise( (resolve, reject) => {
gulp.task(_taskName, (error) => {
if (error) {
reject(error)
}
resolve(_taskName)
});
});
}
performTask(taskName).then(console.log).catch(console.error)
// Example async/await with then/catch
const exampleServiceHandler = async (_taskName) => {
// Perform actions here
try {
return await gulp.task(_taskName) // Resolve the task
} catch (exception) {
return exception;
}
}
exampleServiceHandler(taskName)
.then(console.log)
.catch(console.error)
