Repository: facebook/react
File: packages/react-server/src/ReactFlightServer.js (JavaScript)

Code before:

  if (
    typeof result === 'object' &&
    result !== null &&
    !isClientReference(result)
  ) {
    if (typeof result.then === 'function') {
      // When the return value is in children position we can resolve it immediately,
      // to its value without a wrapper if it's synchronously available.
      const thenable: Thenable<any> = result;
      if (__DEV__) {
        // If the thenable resolves to an element, then it was in a static position,
        // the return value of a Server Component. That doesn't need further validation
        // of keys. The Server Component itself would have had a key.
        thenable.then(resolvedValue => {
          if (
            typeof resolvedValue === 'object' &&
            resolvedValue !== null &&
            resolvedValue.$$typeof === REACT_ELEMENT_TYPE
          ) {
            resolvedValue._store.validated = 1;
          }
        }, voidHandler);
      }
      if (thenable.status === 'fulfilled') {
        return thenable.value;
      }
      // TODO: Once we accept Promises as children on the client, we can just return
      // the thenable here.
      result = createLazyWrapperAroundWakeable(result);
    }

    // Normally we'd serialize an Iterator/AsyncIterator as a single-shot which is not compatible
    // to be rendered as a React Child. However, because we have the function to recreate
    // an iterable from rendering the element again, we can effectively treat it as multi-
    // shot. Therefore we treat this as an Iterable/AsyncIterable, whether it was one or not, by
    // adding a wrapper so that this component effectively renders down to an AsyncIterable.
    const iteratorFn = getIteratorFn(result);
    if (iteratorFn) {
      const iterableChild = result;
      result = {
        [Symbol.iterator]: function () {
          const iterator = iteratorFn.call(iterableChild);
          if (__DEV__) {
            // If this was an Iterator but not a GeneratorFunction we warn because
            // it might have been a mistake. Technically you can make this mistake with
            // GeneratorFunctions and even single-shot Iterables too but it's extra
            // tempting to try to return the value from a generator.
            if (iterator === iterableChild) {
              const isGeneratorComponent =
                // $FlowIgnore[method-unbinding]

Review comment (suggestion):
In particular this special case was a little tricky because this was an early return so bypasses the nested renderModelDestructive below. It's fine semantically because it'll just enter the renderModelDestructive in the retryTask but it's less optimal if we can avoid spawning another task. So I changed it to instead go through the pass below to be able to reuse the task.

Code after:
        }
        return iterator;
      },
    };
    if (__DEV__) {
      (multishot: any)._debugInfo = iterableChild._debugInfo;
    }
    return multishot;
  }
  return result;
}

function renderFunctionComponent<Props>(
  request: Request,
  task: Task,
  key: null | string,
  Component: (p: Props, arg: void) => any,
  props: Props,
  validated: number, // DEV-only
): ReactJSONValue {
  // Reset the task's thenable state before continuing, so that if a later
  // component suspends we can reuse the same task object. If the same
  // component suspends again, the thenable state will be restored.
  const prevThenableState = task.thenableState;
  task.thenableState = null;

  let result;

  let componentDebugInfo: ReactComponentInfo;
  if (__DEV__) {
    if (debugID === null) {
      // We don't have a chunk to assign debug info. We need to outline this
      // component to assign it an ID.
      return outlineTask(request, task);
    } else if (prevThenableState !== null) {
      // This is a replay and we've already emitted the debug info of this component
      // in the first pass. We skip emitting a duplicate line.
      // As a hack we stashed the previous component debug info on this object in DEV.
      componentDebugInfo = (prevThenableState: any)._componentDebugInfo;
    } else {
      // This is a new component in the same task so we can emit more debug info.
      const componentDebugID = debugID;
      const componentName =
        (Component: any).displayName || Component.name || '';
      const componentEnv = (0, request.environmentName)();
      request.pendingChunks++;
      componentDebugInfo = ({
        name: componentName,
        env: componentEnv,
        key: key,
        owner: task.debugOwner,