Skip to content

Commit

Permalink
introduce new afterMaybeAsync helper
Browse files Browse the repository at this point in the history
`after` becomes sync, requiring no return type check for the onFulfilled result.
  • Loading branch information
yaacovCR committed Dec 16, 2022
1 parent 025f26e commit b66bdd3
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 11 deletions.
9 changes: 5 additions & 4 deletions src/execution/execute.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { after } from '../jsutils/after.js';
import { afterMaybeAsync } from '../jsutils/afterMaybeAsync.js';
import { catchAfter } from '../jsutils/catchAfter.js';
import { inspect } from '../jsutils/inspect.js';
import { invariant } from '../jsutils/invariant.js';
Expand Down Expand Up @@ -1282,7 +1283,7 @@ function completeAbstractValue(
const runtimeType = resolveTypeFn(result, contextValue, info, returnType);

if (isPromise(runtimeType)) {
return after(runtimeType, (resolvedRuntimeType) =>
return afterMaybeAsync(runtimeType, (resolvedRuntimeType) =>
completeObjectValue(
exeContext,
ensureValidRuntimeType(
Expand Down Expand Up @@ -1394,7 +1395,7 @@ function completeObjectValue(
const isTypeOf = returnType.isTypeOf(result, exeContext.contextValue, info);

if (isPromise(isTypeOf)) {
return after(isTypeOf, (resolvedIsTypeOf) => {
return afterMaybeAsync(isTypeOf, (resolvedIsTypeOf) => {
if (!resolvedIsTypeOf) {
throw invalidReturnTypeError(returnType, result, fieldNodes);
}
Expand Down Expand Up @@ -2314,7 +2315,7 @@ class DeferredFragmentRecord {
addData(data: PromiseOrValue<ObjMap<unknown> | null>) {
const parentData = this.parentContext?.promise;
if (parentData) {
this._resolve?.(after(parentData, () => data));
this._resolve?.(afterMaybeAsync(parentData, () => data));
return;
}
this._resolve?.(data);
Expand Down Expand Up @@ -2368,7 +2369,7 @@ class StreamRecord {
addItems(items: PromiseOrValue<Array<unknown> | null>) {
const parentData = this.parentContext?.promise;
if (parentData) {
this._resolve?.(after(parentData, () => items));
this._resolve?.(afterMaybeAsync(parentData, () => items));
return;
}
this._resolve?.(items);
Expand Down
8 changes: 1 addition & 7 deletions src/jsutils/after.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
import { isPromise } from './isPromise.js';
import type { PromiseOrValue } from './PromiseOrValue.js';

/**
* Async Helper Function that avoides `.then()`
*
Expand All @@ -11,11 +8,8 @@ import type { PromiseOrValue } from './PromiseOrValue.js';
*/
export async function after<T, R>(
promise: Promise<T>,
onFulfilled: (value: T) => PromiseOrValue<R>,
onFulfilled: (value: T) => R,
): Promise<R> {
const result = onFulfilled(await promise);
if (isPromise(result)) {
return await result;
}
return result;
}
21 changes: 21 additions & 0 deletions src/jsutils/afterMaybeAsync.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { isPromise } from './isPromise.js';
import type { PromiseOrValue } from './PromiseOrValue.js';

/**
* Async Helper Function that avoides `.then()`
*
* It is faster to await a promise prior to returning it from an async function
* than to return a promise with `.then()`.
*
* see: https://github.com/tc39/proposal-faster-promise-adoption
*/
export async function afterMaybeAsync<T, R>(
promise: Promise<T>,
onFulfilled: (value: T) => PromiseOrValue<R>,
): Promise<R> {
const result = onFulfilled(await promise);
if (isPromise(result)) {
return await result;
}
return result;
}

0 comments on commit b66bdd3

Please sign in to comment.