zone-patch-promise-test.js 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. 'use strict';
  2. /**
  3. * @license Angular v<unknown>
  4. * (c) 2010-2022 Google LLC. https://angular.io/
  5. * License: MIT
  6. */
  7. /**
  8. * Promise for async/fakeAsync zoneSpec test
  9. * can support async operation which not supported by zone.js
  10. * such as
  11. * it ('test jsonp in AsyncZone', async() => {
  12. * new Promise(res => {
  13. * jsonp(url, (data) => {
  14. * // success callback
  15. * res(data);
  16. * });
  17. * }).then((jsonpResult) => {
  18. * // get jsonp result.
  19. *
  20. * // user will expect AsyncZoneSpec wait for
  21. * // then, but because jsonp is not zone aware
  22. * // AsyncZone will finish before then is called.
  23. * });
  24. * });
  25. */
  26. Zone.__load_patch('promisefortest', (global, Zone, api) => {
  27. const symbolState = api.symbol('state');
  28. const UNRESOLVED = null;
  29. const symbolParentUnresolved = api.symbol('parentUnresolved');
  30. // patch Promise.prototype.then to keep an internal
  31. // number for tracking unresolved chained promise
  32. // we will decrease this number when the parent promise
  33. // being resolved/rejected and chained promise was
  34. // scheduled as a microTask.
  35. // so we can know such kind of chained promise still
  36. // not resolved in AsyncTestZone
  37. Promise[api.symbol('patchPromiseForTest')] = function patchPromiseForTest() {
  38. let oriThen = Promise[Zone.__symbol__('ZonePromiseThen')];
  39. if (oriThen) {
  40. return;
  41. }
  42. oriThen = Promise[Zone.__symbol__('ZonePromiseThen')] = Promise.prototype.then;
  43. Promise.prototype.then = function () {
  44. const chained = oriThen.apply(this, arguments);
  45. if (this[symbolState] === UNRESOLVED) {
  46. // parent promise is unresolved.
  47. const asyncTestZoneSpec = Zone.current.get('AsyncTestZoneSpec');
  48. if (asyncTestZoneSpec) {
  49. asyncTestZoneSpec.unresolvedChainedPromiseCount++;
  50. chained[symbolParentUnresolved] = true;
  51. }
  52. }
  53. return chained;
  54. };
  55. };
  56. Promise[api.symbol('unPatchPromiseForTest')] = function unpatchPromiseForTest() {
  57. // restore origin then
  58. const oriThen = Promise[Zone.__symbol__('ZonePromiseThen')];
  59. if (oriThen) {
  60. Promise.prototype.then = oriThen;
  61. Promise[Zone.__symbol__('ZonePromiseThen')] = undefined;
  62. }
  63. };
  64. });