You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							67 lines
						
					
					
						
							2.1 KiB
						
					
					
				
			
		
		
	
	
							67 lines
						
					
					
						
							2.1 KiB
						
					
					
				| "use strict";
 | |
| 
 | |
| // rawAsap provides everything we need except exception management.
 | |
| var rawAsap = require("./raw");
 | |
| // RawTasks are recycled to reduce GC churn.
 | |
| var freeTasks = [];
 | |
| // We queue errors to ensure they are thrown in right order (FIFO).
 | |
| // Array-as-queue is good enough here, since we are just dealing with exceptions.
 | |
| var pendingErrors = [];
 | |
| var requestErrorThrow = rawAsap.makeRequestCallFromTimer(throwFirstError);
 | |
| 
 | |
| function throwFirstError() {
 | |
|     if (pendingErrors.length) {
 | |
|         throw pendingErrors.shift();
 | |
|     }
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Calls a task as soon as possible after returning, in its own event, with priority
 | |
|  * over other events like animation, reflow, and repaint. An error thrown from an
 | |
|  * event will not interrupt, nor even substantially slow down the processing of
 | |
|  * other events, but will be rather postponed to a lower priority event.
 | |
|  * @param {{call}} task A callable object, typically a function that takes no
 | |
|  * arguments.
 | |
|  */
 | |
| module.exports = asap;
 | |
| function asap(task) {
 | |
|     var rawTask;
 | |
|     if (freeTasks.length) {
 | |
|         rawTask = freeTasks.pop();
 | |
|     } else {
 | |
|         rawTask = new RawTask();
 | |
|     }
 | |
|     rawTask.task = task;
 | |
|     rawAsap(rawTask);
 | |
| }
 | |
| 
 | |
| // We wrap tasks with recyclable task objects.  A task object implements
 | |
| // `call`, just like a function.
 | |
| function RawTask() {
 | |
|     this.task = null;
 | |
| }
 | |
| 
 | |
| // The sole purpose of wrapping the task is to catch the exception and recycle
 | |
| // the task object after its single use.
 | |
| RawTask.prototype.call = function () {
 | |
|     try {
 | |
|         this.task.call();
 | |
|     } catch (error) {
 | |
|         if (asap.onerror) {
 | |
|             // This hook exists purely for testing purposes.
 | |
|             // Its name will be periodically randomized to break any code that
 | |
|             // depends on its existence.
 | |
|             asap.onerror(error);
 | |
|         } else {
 | |
|             // In a web browser, exceptions are not fatal. However, to avoid
 | |
|             // slowing down the queue of pending tasks, we rethrow the error in a
 | |
|             // lower priority turn.
 | |
|             pendingErrors.push(error);
 | |
|             requestErrorThrow();
 | |
|         }
 | |
|     } finally {
 | |
|         this.task = null;
 | |
|         freeTasks[freeTasks.length] = this;
 | |
|     }
 | |
| };
 |