Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.
 
 
 
 
 
 

165 строки
3.9 KiB

  1. /**
  2. * Copyright © Magento, Inc. All rights reserved.
  3. * See COPYING.txt for license details.
  4. */
  5. define([
  6. 'underscore',
  7. 'domReady!'
  8. ], function (_) {
  9. 'use strict';
  10. var context = require.s.contexts._,
  11. execCb = context.execCb,
  12. registry = context.registry,
  13. callbacks = [],
  14. retries = 10,
  15. updateDelay = 1,
  16. ready,
  17. update;
  18. /**
  19. * Checks if provided callback already exists in the callbacks list.
  20. *
  21. * @param {Object} callback - Callback object to be checked.
  22. * @returns {Boolean}
  23. */
  24. function isSubscribed(callback) {
  25. return !!_.findWhere(callbacks, callback);
  26. }
  27. /**
  28. * Checks if provided module is rejected during load.
  29. *
  30. * @param {Object} module - Module to be checked.
  31. * @return {Boolean}
  32. */
  33. function isRejected(module) {
  34. return registry[module.id] && (registry[module.id].inited || registry[module.id].error);
  35. }
  36. /**
  37. * Checks if provided module had path fallback triggered.
  38. *
  39. * @param {Object} module - Module to be checked.
  40. * @return {Boolean}
  41. */
  42. function isPathFallback(module) {
  43. return registry[module.id] && registry[module.id].events.error;
  44. }
  45. /**
  46. * Checks if provided module has unresolved dependencies.
  47. *
  48. * @param {Object} module - Module to be checked.
  49. * @returns {Boolean}
  50. */
  51. function isPending(module) {
  52. if (!module.depCount) {
  53. return false;
  54. }
  55. return module.depCount >
  56. _.filter(module.depMaps, isRejected).length + _.filter(module.depMaps, isPathFallback).length;
  57. }
  58. /**
  59. * Checks if requirejs's registry object contains pending modules.
  60. *
  61. * @returns {Boolean}
  62. */
  63. function hasPending() {
  64. return _.some(registry, isPending);
  65. }
  66. /**
  67. * Checks if 'resolver' module is in ready
  68. * state and that there are no pending modules.
  69. *
  70. * @returns {Boolean}
  71. */
  72. function isReady() {
  73. return ready && !hasPending();
  74. }
  75. /**
  76. * Invokes provided callback handler.
  77. *
  78. * @param {Object} callback
  79. */
  80. function invoke(callback) {
  81. callback.handler.call(callback.ctx);
  82. }
  83. /**
  84. * Sets 'resolver' module to a ready state
  85. * and invokes pending callbacks.
  86. */
  87. function resolve() {
  88. ready = true;
  89. callbacks.splice(0).forEach(invoke);
  90. }
  91. /**
  92. * Drops 'ready' flag and runs the update process.
  93. */
  94. function tick() {
  95. ready = false;
  96. update(retries);
  97. }
  98. /**
  99. * Adds callback which will be invoked
  100. * when all of the pending modules are initiated.
  101. *
  102. * @param {Function} handler - 'Ready' event handler function.
  103. * @param {Object} [ctx] - Optional context with which handler
  104. * will be invoked.
  105. */
  106. function subscribe(handler, ctx) {
  107. var callback = {
  108. handler: handler,
  109. ctx: ctx
  110. };
  111. if (!isSubscribed(callback)) {
  112. callbacks.push(callback);
  113. if (isReady()) {
  114. _.defer(tick);
  115. }
  116. }
  117. }
  118. /**
  119. * Checks for all modules to be initiated
  120. * and invokes pending callbacks if it's so.
  121. *
  122. * @param {Number} [retry] - Number of retries
  123. * that will be used to repeat the 'update' function
  124. * invokation in case if there are no pending requests.
  125. */
  126. update = _.debounce(function (retry) {
  127. if (!hasPending()) {
  128. retry ? update(--retry) : resolve();
  129. }
  130. }, updateDelay);
  131. /**
  132. * Overrides requirejs's original 'execCb' method
  133. * in order to track pending modules.
  134. *
  135. * @returns {*} Result of original method call.
  136. */
  137. context.execCb = function () {
  138. var exported = execCb.apply(context, arguments);
  139. tick();
  140. return exported;
  141. };
  142. return subscribe;
  143. });