mapAsyncIterator.mjs 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. /**
  2. * Given an AsyncIterable and a callback function, return an AsyncIterator
  3. * which produces values mapped via calling the callback function.
  4. */
  5. export function mapAsyncIterator(iterable, callback) {
  6. const iterator = iterable[Symbol.asyncIterator]();
  7. async function mapResult(result) {
  8. if (result.done) {
  9. return result;
  10. }
  11. try {
  12. return {
  13. value: await callback(result.value),
  14. done: false,
  15. };
  16. } catch (error) {
  17. /* c8 ignore start */
  18. // FIXME: add test case
  19. if (typeof iterator.return === 'function') {
  20. try {
  21. await iterator.return();
  22. } catch (_e) {
  23. /* ignore error */
  24. }
  25. }
  26. throw error;
  27. /* c8 ignore stop */
  28. }
  29. }
  30. return {
  31. async next() {
  32. return mapResult(await iterator.next());
  33. },
  34. async return() {
  35. // If iterator.return() does not exist, then type R must be undefined.
  36. return typeof iterator.return === 'function'
  37. ? mapResult(await iterator.return())
  38. : {
  39. value: undefined,
  40. done: true,
  41. };
  42. },
  43. async throw(error) {
  44. if (typeof iterator.throw === 'function') {
  45. return mapResult(await iterator.throw(error));
  46. }
  47. throw error;
  48. },
  49. [Symbol.asyncIterator]() {
  50. return this;
  51. },
  52. };
  53. }