From c2a547bdf84e9ca129193b982aad1d99a72eaa2d Mon Sep 17 00:00:00 2001 From: Marcelo Shima Date: Fri, 3 Apr 2020 12:01:35 -0300 Subject: [PATCH] Implement cancellable tasks. (#1204) --- lib/index.js | 18 +++++++++++++++++- test/base.js | 12 ++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/lib/index.js b/lib/index.js index 09598a5b..c678a16a 100644 --- a/lib/index.js +++ b/lib/index.js @@ -650,11 +650,20 @@ class Generator extends EventEmitter { self.emit(`method:${methodName}`); runAsync(function() { + if (task.cancellable && !self._running) { + return Promise.resolve(); + } + self.async = () => this.async(); self.runningState = { namespace, queueName, methodName }; return method.apply(self, self.args); })() .then(function() { + if (task.cancellable && !self._running) { + completed(); + return; + } + delete self.runningState; const eventName = `done$${namespace || 'unknownnamespace'}#${methodName}`; debug(`Emiting event ${eventName}`); @@ -682,6 +691,13 @@ class Generator extends EventEmitter { ); } + /** + * Ignore cancellable tasks. + */ + cancelCancellableTasks() { + this._running = false; + } + /** * Runs the generator, scheduling prototype methods on a run queue. Method names * will determine the order each method is run. Methods without special names @@ -729,7 +745,7 @@ class Generator extends EventEmitter { const item = property.value ? property.value : property.get.call(self); const priority = self._queues[name]; - let taskOptions = { ...priority }; + let taskOptions = { ...priority, cancellable: true }; // Name points to a function; run it! if (typeof item === 'function') { diff --git a/test/base.js b/test/base.js index ec5e20ac..d5a2198e 100644 --- a/test/base.js +++ b/test/base.js @@ -497,6 +497,18 @@ describe('Base', () => { assert(fs.existsSync(this.testGen.destinationPath('foo.txt'))); }); }); + + it('can cancel cancellable tasks', function(done) { + this.TestGenerator.prototype.cancel = function() { + this.cancelCancellableTasks(); + }; + + this.TestGenerator.prototype.throwing = () => { + throw new Error('not thrown'); + }; + + this.testGen.run().then(done); + }); }); describe('#argument()', () => {