|
9 | 9 |
|
10 | 10 | import { forEach, isCollection } from 'iterall'; |
11 | 11 | import { GraphQLError, locatedError } from '../error'; |
| 12 | +import getPromise from '../jsutils/getPromise'; |
12 | 13 | import invariant from '../jsutils/invariant'; |
13 | 14 | import isInvalid from '../jsutils/isInvalid'; |
14 | 15 | import isNullish from '../jsutils/isNullish'; |
15 | 16 | import memoize3 from '../jsutils/memoize3'; |
| 17 | +import promiseReduce from '../jsutils/promiseReduce'; |
16 | 18 | import type { ObjMap } from '../jsutils/ObjMap'; |
17 | 19 | import type { MaybePromise } from '../jsutils/MaybePromise'; |
18 | 20 |
|
@@ -465,33 +467,33 @@ function executeFieldsSerially( |
465 | 467 | sourceValue: mixed, |
466 | 468 | path: ResponsePath | void, |
467 | 469 | fields: ObjMap<Array<FieldNode>>, |
468 | | -): Promise<ObjMap<mixed>> { |
469 | | - return Object.keys(fields).reduce( |
470 | | - (prevPromise, responseName) => |
471 | | - prevPromise.then(results => { |
472 | | - const fieldNodes = fields[responseName]; |
473 | | - const fieldPath = addPath(path, responseName); |
474 | | - const result = resolveField( |
475 | | - exeContext, |
476 | | - parentType, |
477 | | - sourceValue, |
478 | | - fieldNodes, |
479 | | - fieldPath, |
480 | | - ); |
481 | | - if (result === undefined) { |
482 | | - return results; |
483 | | - } |
484 | | - const promise = getPromise(result); |
485 | | - if (promise) { |
486 | | - return promise.then(resolvedResult => { |
487 | | - results[responseName] = resolvedResult; |
488 | | - return results; |
489 | | - }); |
490 | | - } |
491 | | - results[responseName] = result; |
| 470 | +): MaybePromise<ObjMap<mixed>> { |
| 471 | + return promiseReduce( |
| 472 | + Object.keys(fields), |
| 473 | + (results, responseName) => { |
| 474 | + const fieldNodes = fields[responseName]; |
| 475 | + const fieldPath = addPath(path, responseName); |
| 476 | + const result = resolveField( |
| 477 | + exeContext, |
| 478 | + parentType, |
| 479 | + sourceValue, |
| 480 | + fieldNodes, |
| 481 | + fieldPath, |
| 482 | + ); |
| 483 | + if (result === undefined) { |
492 | 484 | return results; |
493 | | - }), |
494 | | - Promise.resolve({}), |
| 485 | + } |
| 486 | + const promise = getPromise(result); |
| 487 | + if (promise) { |
| 488 | + return promise.then(resolvedResult => { |
| 489 | + results[responseName] = resolvedResult; |
| 490 | + return results; |
| 491 | + }); |
| 492 | + } |
| 493 | + results[responseName] = result; |
| 494 | + return results; |
| 495 | + }, |
| 496 | + Object.create(null), |
495 | 497 | ); |
496 | 498 | } |
497 | 499 |
|
@@ -1346,20 +1348,6 @@ export const defaultFieldResolver: GraphQLFieldResolver<any, *> = function( |
1346 | 1348 | } |
1347 | 1349 | }; |
1348 | 1350 |
|
1349 | | -/** |
1350 | | - * Only returns the value if it acts like a Promise, i.e. has a "then" function, |
1351 | | - * otherwise returns void. |
1352 | | - */ |
1353 | | -function getPromise<T>(value: Promise<T> | mixed): Promise<T> | void { |
1354 | | - if ( |
1355 | | - typeof value === 'object' && |
1356 | | - value !== null && |
1357 | | - typeof value.then === 'function' |
1358 | | - ) { |
1359 | | - return (value: any); |
1360 | | - } |
1361 | | -} |
1362 | | - |
1363 | 1351 | /** |
1364 | 1352 | * This method looks up the field on the given type defintion. |
1365 | 1353 | * It has special casing for the two introspection fields, __schema |
|
0 commit comments