Skip to content

Commit

Permalink
api-fetch: simplify the code that executes the handlers (#24999)
Browse files Browse the repository at this point in the history
* apiFetch: simplify the promise-chaining code

* Use reduce(Right) to compose middlewares
  • Loading branch information
jsnajdr authored Sep 2, 2020
1 parent 0ccabe7 commit ee36854
Showing 1 changed file with 20 additions and 28 deletions.
48 changes: 20 additions & 28 deletions packages/api-fetch/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,36 +120,28 @@ function setFetchHandler( newFetchHandler ) {
}

function apiFetch( options ) {
const steps = [ ...middlewares, fetchHandler ];

const createRunStep = ( index ) => ( workingOptions ) => {
const step = steps[ index ];
if ( index === steps.length - 1 ) {
return step( workingOptions );
// creates a nested function chain that calls all middlewares and finally the `fetchHandler`,
// converting `middlewares = [ m1, m2, m3 ]` into:
// ```
// opts1 => m1( opts1, opts2 => m2( opts2, opts3 => m3( opts3, fetchHandler ) ) );
// ```
const enhancedHandler = middlewares.reduceRight( ( next, middleware ) => {
return ( workingOptions ) => middleware( workingOptions, next );
}, fetchHandler );

return enhancedHandler( options ).catch( ( error ) => {
if ( error.code !== 'rest_cookie_invalid_nonce' ) {
return Promise.reject( error );
}

const next = createRunStep( index + 1 );
return step( workingOptions, next );
};

return new Promise( ( resolve, reject ) => {
createRunStep( 0 )( options )
.then( resolve )
.catch( ( error ) => {
if ( error.code !== 'rest_cookie_invalid_nonce' ) {
return reject( error );
}

// If the nonce is invalid, refresh it and try again.
window
.fetch( apiFetch.nonceEndpoint )
.then( checkStatus )
.then( ( data ) => data.text() )
.then( ( text ) => {
apiFetch.nonceMiddleware.nonce = text;
apiFetch( options ).then( resolve ).catch( reject );
} )
.catch( reject );
// If the nonce is invalid, refresh it and try again.
return window
.fetch( apiFetch.nonceEndpoint )
.then( checkStatus )
.then( ( data ) => data.text() )
.then( ( text ) => {
apiFetch.nonceMiddleware.nonce = text;
return apiFetch( options );
} );
} );
}
Expand Down

0 comments on commit ee36854

Please sign in to comment.