[for of 재귀 test]

function* gen() {
  const arr = [Promise.resolve(1), Promise.resolve(2), Promise.resolve(3)];
	// const arr = [1, 2, 3];
  for (const a of arr) {
    yield a;
  }
}

const testGen = gen();

const testFunc = iter => {
  log(iter);
  for (const a of iter) {
    log(a);
    return a instanceof Promise
      ? a.then(res => testFunc(iter))
      : testFunc(iter);
  }
};

testFunc(testGen);

[바벨로 변환]

function _createForOfIteratorHelper(o, allowArrayLike) {
  log("iterator Init");
  var it;
  if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) {
    if (
      Array.isArray(o) ||
      (it = _unsupportedIterableToArray(o)) ||
      (allowArrayLike && o && typeof o.length === "number")
    ) {
      if (it) o = it;
      var i = 0;
      var F = function F() {};
      return {
        s: F,
        n: function n() {
          if (i >= o.length) return { done: true };
          return { done: false, value: o[i++] };
        },
        e: function e(_e) {
          throw _e;
        },
        f: F
      };
    }
    throw new TypeError(
      "Invalid attempt to iterate non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."
    );
  }
  var normalCompletion = true,
    didErr = false,
    err;
  return {
    s: function s() {
      it = o[Symbol.iterator]();
    },
    n: function n() {
      var step = it.next();
      normalCompletion = step.done;
      return step;
    },
    e: function e(_e2) {
      didErr = true;
      err = _e2;
    },
    f: function f() {
      try {
        if (!normalCompletion && it.return != null) {
          log("iterator Return");
          it.return();
        }
      } finally {
        log("iterator Finally");
        if (didErr) throw err;
      }
    }
  };
}
var testFunc = function testFunc(iter) {
  log("test Init");

  var _iterator = _createForOfIteratorHelper(iter),
    _step;

  try {
    for (_iterator.s(); !(_step = _iterator.n()).done; ) {
      var a = _step.value;
      log(a);
      return _instanceof(a, Promise)
        ? a.then(function(res) {
            return testFunc(iter);
          })
        : testFunc(iter);
    }
  } catch (err) {
    _iterator.e(err);
  } finally {
    log("test Finally!");
    _iterator.f();
  }

  return 0;
};

[결과]

const arr = [1, 2, 3]인 경우

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/5b0b3d91-7e15-46b9-add9-583690a271bd/Untitled.png

const arr = [Promise.resolve(1), Promise.resolve(2), Promise.resolve(3)]인 경우

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/60ab5394-c411-49b3-8e39-d538a8ecd187/Untitled.png

const arr = [1, 2, Promise.resolve(1), 3, 4, 5];

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/9ceef62a-c728-4158-9208-bffe914f43a8/Untitled.png

Generator.prototype.return()