zone-patch-fetch.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. /**
  2. * @license
  3. * Copyright Google Inc. All Rights Reserved.
  4. *
  5. * Use of this source code is governed by an MIT-style license that can be
  6. * found in the LICENSE file at https://angular.io/license
  7. */
  8. (function (global, factory) {
  9. typeof exports === 'object' && typeof module !== 'undefined' ? factory() :
  10. typeof define === 'function' && define.amd ? define(factory) :
  11. (factory());
  12. }(this, (function () { 'use strict';
  13. /**
  14. * @license
  15. * Copyright Google Inc. All Rights Reserved.
  16. *
  17. * Use of this source code is governed by an MIT-style license that can be
  18. * found in the LICENSE file at https://angular.io/license
  19. */
  20. /**
  21. * @fileoverview
  22. * @suppress {missingRequire}
  23. */
  24. Zone.__load_patch('fetch', function (global, Zone, api) {
  25. var fetch = global['fetch'];
  26. if (typeof fetch !== 'function') {
  27. return;
  28. }
  29. var originalFetch = global[api.symbol('fetch')];
  30. if (originalFetch) {
  31. // restore unpatched fetch first
  32. fetch = originalFetch;
  33. }
  34. var ZoneAwarePromise = global.Promise;
  35. var symbolThenPatched = api.symbol('thenPatched');
  36. var fetchTaskScheduling = api.symbol('fetchTaskScheduling');
  37. var fetchTaskAborting = api.symbol('fetchTaskAborting');
  38. var OriginalAbortController = global['AbortController'];
  39. var supportAbort = typeof OriginalAbortController === 'function';
  40. var abortNative = null;
  41. if (supportAbort) {
  42. global['AbortController'] = function () {
  43. var abortController = new OriginalAbortController();
  44. var signal = abortController.signal;
  45. signal.abortController = abortController;
  46. return abortController;
  47. };
  48. abortNative = api.patchMethod(OriginalAbortController.prototype, 'abort', function (delegate) { return function (self, args) {
  49. if (self.task) {
  50. return self.task.zone.cancelTask(self.task);
  51. }
  52. return delegate.apply(self, args);
  53. }; });
  54. }
  55. var placeholder = function () { };
  56. global['fetch'] = function () {
  57. var _this = this;
  58. var args = Array.prototype.slice.call(arguments);
  59. var options = args.length > 1 ? args[1] : null;
  60. var signal = options && options.signal;
  61. return new Promise(function (res, rej) {
  62. var task = Zone.current.scheduleMacroTask('fetch', placeholder, { fetchArgs: args }, function () {
  63. var fetchPromise;
  64. var zone = Zone.current;
  65. try {
  66. zone[fetchTaskScheduling] = true;
  67. fetchPromise = fetch.apply(_this, args);
  68. }
  69. catch (error) {
  70. rej(error);
  71. return;
  72. }
  73. finally {
  74. zone[fetchTaskScheduling] = false;
  75. }
  76. if (!(fetchPromise instanceof ZoneAwarePromise)) {
  77. var ctor = fetchPromise.constructor;
  78. if (!ctor[symbolThenPatched]) {
  79. api.patchThen(ctor);
  80. }
  81. }
  82. fetchPromise.then(function (resource) {
  83. if (task.state !== 'notScheduled') {
  84. task.invoke();
  85. }
  86. res(resource);
  87. }, function (error) {
  88. if (task.state !== 'notScheduled') {
  89. task.invoke();
  90. }
  91. rej(error);
  92. });
  93. }, function () {
  94. if (!supportAbort) {
  95. rej('No AbortController supported, can not cancel fetch');
  96. return;
  97. }
  98. if (signal && signal.abortController && !signal.aborted &&
  99. typeof signal.abortController.abort === 'function' && abortNative) {
  100. try {
  101. Zone.current[fetchTaskAborting] = true;
  102. abortNative.call(signal.abortController);
  103. }
  104. finally {
  105. Zone.current[fetchTaskAborting] = false;
  106. }
  107. }
  108. else {
  109. rej('cancel fetch need a AbortController.signal');
  110. }
  111. });
  112. if (signal && signal.abortController) {
  113. signal.abortController.task = task;
  114. }
  115. });
  116. };
  117. });
  118. })));