Blame view

node_modules/asap/browser-asap.js 2.13 KB
ce4c83ff   wxy   初始提交
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
  "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;
      }
  };