scheduler-unstable_post_task.development.js 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. /**
  2. * @license React
  3. * scheduler-unstable_post_task.development.js
  4. *
  5. * Copyright (c) Facebook, Inc. and its affiliates.
  6. *
  7. * This source code is licensed under the MIT license found in the
  8. * LICENSE file in the root directory of this source tree.
  9. */
  10. 'use strict';
  11. if (process.env.NODE_ENV !== "production") {
  12. (function() {
  13. 'use strict';
  14. // TODO: Use symbols?
  15. var ImmediatePriority = 1;
  16. var UserBlockingPriority = 2;
  17. var NormalPriority = 3;
  18. var LowPriority = 4;
  19. var IdlePriority = 5;
  20. var perf = window.performance;
  21. var setTimeout = window.setTimeout; // Use experimental Chrome Scheduler postTask API.
  22. var scheduler = global.scheduler;
  23. var getCurrentTime = perf.now.bind(perf);
  24. var unstable_now = getCurrentTime; // Scheduler periodically yields in case there is other work on the main
  25. // thread, like user events. By default, it yields multiple times per frame.
  26. // It does not attempt to align with frame boundaries, since most tasks don't
  27. // need to be frame aligned; for those that do, use requestAnimationFrame.
  28. var yieldInterval = 5;
  29. var deadline = 0;
  30. var currentPriorityLevel_DEPRECATED = NormalPriority; // `isInputPending` is not available. Since we have no way of knowing if
  31. // there's pending input, always yield at the end of the frame.
  32. function unstable_shouldYield() {
  33. return getCurrentTime() >= deadline;
  34. }
  35. function unstable_requestPaint() {// Since we yield every frame regardless, `requestPaint` has no effect.
  36. }
  37. function unstable_scheduleCallback(priorityLevel, callback, options) {
  38. var postTaskPriority;
  39. switch (priorityLevel) {
  40. case ImmediatePriority:
  41. case UserBlockingPriority:
  42. postTaskPriority = 'user-blocking';
  43. break;
  44. case LowPriority:
  45. case NormalPriority:
  46. postTaskPriority = 'user-visible';
  47. break;
  48. case IdlePriority:
  49. postTaskPriority = 'background';
  50. break;
  51. default:
  52. postTaskPriority = 'user-visible';
  53. break;
  54. }
  55. var controller = new TaskController();
  56. var postTaskOptions = {
  57. priority: postTaskPriority,
  58. delay: typeof options === 'object' && options !== null ? options.delay : 0,
  59. signal: controller.signal
  60. };
  61. var node = {
  62. _controller: controller
  63. };
  64. scheduler.postTask(runTask.bind(null, priorityLevel, postTaskPriority, node, callback), postTaskOptions).catch(handleAbortError);
  65. return node;
  66. }
  67. function runTask(priorityLevel, postTaskPriority, node, callback) {
  68. deadline = getCurrentTime() + yieldInterval;
  69. try {
  70. currentPriorityLevel_DEPRECATED = priorityLevel;
  71. var _didTimeout_DEPRECATED = false;
  72. var result = callback(_didTimeout_DEPRECATED);
  73. if (typeof result === 'function') {
  74. // Assume this is a continuation
  75. var continuation = result;
  76. var continuationController = new TaskController();
  77. var continuationOptions = {
  78. priority: postTaskPriority,
  79. signal: continuationController.signal
  80. }; // Update the original callback node's controller, since even though we're
  81. // posting a new task, conceptually it's the same one.
  82. node._controller = continuationController;
  83. scheduler.postTask(runTask.bind(null, priorityLevel, postTaskPriority, node, continuation), continuationOptions).catch(handleAbortError);
  84. }
  85. } catch (error) {
  86. // We're inside a `postTask` promise. If we don't handle this error, then it
  87. // will trigger an "Unhandled promise rejection" error. We don't want that,
  88. // but we do want the default error reporting behavior that normal
  89. // (non-Promise) tasks get for unhandled errors.
  90. //
  91. // So we'll re-throw the error inside a regular browser task.
  92. setTimeout(function () {
  93. throw error;
  94. });
  95. } finally {
  96. currentPriorityLevel_DEPRECATED = NormalPriority;
  97. }
  98. }
  99. function handleAbortError(error) {// Abort errors are an implementation detail. We don't expose the
  100. // TaskController to the user, nor do we expose the promise that is returned
  101. // from `postTask`. So we should suppress them, since there's no way for the
  102. // user to handle them.
  103. }
  104. function unstable_cancelCallback(node) {
  105. var controller = node._controller;
  106. controller.abort();
  107. }
  108. function unstable_runWithPriority(priorityLevel, callback) {
  109. var previousPriorityLevel = currentPriorityLevel_DEPRECATED;
  110. currentPriorityLevel_DEPRECATED = priorityLevel;
  111. try {
  112. return callback();
  113. } finally {
  114. currentPriorityLevel_DEPRECATED = previousPriorityLevel;
  115. }
  116. }
  117. function unstable_getCurrentPriorityLevel() {
  118. return currentPriorityLevel_DEPRECATED;
  119. }
  120. function unstable_next(callback) {
  121. var priorityLevel;
  122. switch (currentPriorityLevel_DEPRECATED) {
  123. case ImmediatePriority:
  124. case UserBlockingPriority:
  125. case NormalPriority:
  126. // Shift down to normal priority
  127. priorityLevel = NormalPriority;
  128. break;
  129. default:
  130. // Anything lower than normal priority should remain at the current level.
  131. priorityLevel = currentPriorityLevel_DEPRECATED;
  132. break;
  133. }
  134. var previousPriorityLevel = currentPriorityLevel_DEPRECATED;
  135. currentPriorityLevel_DEPRECATED = priorityLevel;
  136. try {
  137. return callback();
  138. } finally {
  139. currentPriorityLevel_DEPRECATED = previousPriorityLevel;
  140. }
  141. }
  142. function unstable_wrapCallback(callback) {
  143. var parentPriorityLevel = currentPriorityLevel_DEPRECATED;
  144. return function () {
  145. var previousPriorityLevel = currentPriorityLevel_DEPRECATED;
  146. currentPriorityLevel_DEPRECATED = parentPriorityLevel;
  147. try {
  148. return callback();
  149. } finally {
  150. currentPriorityLevel_DEPRECATED = previousPriorityLevel;
  151. }
  152. };
  153. }
  154. function unstable_forceFrameRate() {}
  155. function unstable_pauseExecution() {}
  156. function unstable_continueExecution() {}
  157. function unstable_getFirstCallbackNode() {
  158. return null;
  159. } // Currently no profiling build
  160. var unstable_Profiling = null;
  161. exports.unstable_IdlePriority = IdlePriority;
  162. exports.unstable_ImmediatePriority = ImmediatePriority;
  163. exports.unstable_LowPriority = LowPriority;
  164. exports.unstable_NormalPriority = NormalPriority;
  165. exports.unstable_Profiling = unstable_Profiling;
  166. exports.unstable_UserBlockingPriority = UserBlockingPriority;
  167. exports.unstable_cancelCallback = unstable_cancelCallback;
  168. exports.unstable_continueExecution = unstable_continueExecution;
  169. exports.unstable_forceFrameRate = unstable_forceFrameRate;
  170. exports.unstable_getCurrentPriorityLevel = unstable_getCurrentPriorityLevel;
  171. exports.unstable_getFirstCallbackNode = unstable_getFirstCallbackNode;
  172. exports.unstable_next = unstable_next;
  173. exports.unstable_now = unstable_now;
  174. exports.unstable_pauseExecution = unstable_pauseExecution;
  175. exports.unstable_requestPaint = unstable_requestPaint;
  176. exports.unstable_runWithPriority = unstable_runWithPriority;
  177. exports.unstable_scheduleCallback = unstable_scheduleCallback;
  178. exports.unstable_shouldYield = unstable_shouldYield;
  179. exports.unstable_wrapCallback = unstable_wrapCallback;
  180. })();
  181. }