Browse Source

Improved ActionQueue.

Maciej Bukowski 6 năm trước cách đây
mục cha
commit
2dd52ee69b
1 tập tin đã thay đổi với 11 bổ sung50 xóa
  1. 11 50
      packages/ckeditor5-watchdog/src/contextwatchdog.js

+ 11 - 50
packages/ckeditor5-watchdog/src/contextwatchdog.js

@@ -393,11 +393,8 @@ export default class ContextWatchdog extends Watchdog {
 // An action queue that allows queuing async functions.
 class ActionQueue {
 	constructor() {
-		// @type {Array.<Function>}
-		this._queuedActions = [];
-
-		// @type {WeakMap.<Function, Function>}
-		this._resolveCallbacks = new WeakMap();
+		// @type {Promise}
+		this._promiseQueue = Promise.resolve();
 
 		// @type {Array.<Function>}
 		this._onEmptyCallbacks = [];
@@ -415,56 +412,20 @@ class ActionQueue {
 	// @param {Function} action A function that should be enqueued.
 	// @returns {Promise}
 	enqueue( action ) {
-		this._queuedActions.push( action );
-
-		if ( this._queuedActions.length > 1 ) {
-			// This means that the action handler is already running.
-			// Hence we can just register the resolve callback and wait.
-			return new Promise( res => {
-				this._resolveCallbacks.set( action, res );
-			} );
-		}
-
-		return new Promise( ( res, rej ) => {
-			this._handleActions( res, rej );
-		} );
-	}
-
-	// It handles queued actions one by one.
-	// @param {Function} res
-	// @param {Function} rej
-	_handleActions( res, rej ) {
-		const action = this._queuedActions[ 0 ];
-
-		if ( !action ) {
-			this._onEmptyCallbacks.forEach( cb => cb() );
+		let nonErrorQueue;
 
-			res();
-
-			return;
-		}
-
-		const resolve = this._resolveCallbacks.get( action );
-
-		return Promise.resolve()
-			.then( () => action() )
+		const queueWithAction = this._promiseQueue
+			.then( action )
 			.then( () => {
-				if ( resolve ) {
-					resolve();
+				if ( this._promiseQueue === nonErrorQueue ) {
+					this._onEmptyCallbacks.forEach( cb => cb() );
 				}
+			} );
 
-				this._queuedActions.shift();
-
-				return this._handleActions( res, rej );
-			} )
-			.catch( err => {
-				rej( err );
-
-				this._queuedActions.shift();
+		// Catch all errors in the main queue to stack promises even if an error occurred in the past.
+		nonErrorQueue = this._promiseQueue = queueWithAction.catch( () => { } );
 
-				// Run pending actions even if an error has happened to unlock the queue.
-				return this._handleActions( res, rej );
-			} );
+		return queueWithAction;
 	}
 }