AsyncIteratorClose.js 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. 'use strict';
  2. var GetIntrinsic = require('get-intrinsic');
  3. var $SyntaxError = GetIntrinsic('%SyntaxError%');
  4. var $TypeError = GetIntrinsic('%TypeError%');
  5. var $Promise = GetIntrinsic('%Promise%', true);
  6. var Call = require('./Call');
  7. var CompletionRecord = require('./CompletionRecord');
  8. var GetMethod = require('./GetMethod');
  9. var Type = require('./Type');
  10. var assertRecord = require('../helpers/assertRecord');
  11. var callBound = require('call-bind/callBound');
  12. var $then = callBound('Promise.prototype.then', true);
  13. // https://262.ecma-international.org/12.0/#sec-asynciteratorclose
  14. module.exports = function AsyncIteratorClose(iteratorRecord, completion) {
  15. assertRecord(Type, 'Iterator Record', 'iteratorRecord', iteratorRecord); // step 1
  16. if (!(completion instanceof CompletionRecord)) {
  17. throw new $TypeError('Assertion failed: completion is not a Completion Record instance'); // step 2
  18. }
  19. if (!$then) {
  20. throw new $SyntaxError('This environment does not support Promises.');
  21. }
  22. var iterator = iteratorRecord['[[Iterator]]']; // step 3
  23. return $then(
  24. $then(
  25. $then(
  26. new $Promise(function (resolve) {
  27. resolve(GetMethod(iterator, 'return')); // step 4
  28. // resolve(Call(ret, iterator, [])); // step 6
  29. }),
  30. function (returnV) { // step 5.a
  31. if (typeof returnV === 'undefined') {
  32. return completion; // step 5.b
  33. }
  34. return Call(returnV, iterator); // step 5.c, 5.d.
  35. }
  36. ),
  37. null,
  38. function (e) {
  39. if (completion.type() === 'throw') {
  40. completion['?'](); // step 6
  41. } else {
  42. throw e; // step 7
  43. }
  44. }
  45. ),
  46. function (innerResult) { // step 8
  47. if (completion.type() === 'throw') {
  48. completion['?'](); // step 6
  49. }
  50. if (Type(innerResult) !== 'Object') {
  51. throw new $TypeError('`innerResult` must be an Object'); // step 10
  52. }
  53. return completion;
  54. }
  55. );
  56. };