@@ -256,19 +256,26 @@ export default class App {
256
256
this . initComponentInCache ( )
257
257
}
258
258
259
- let componentView = this . getComponentView ( )
260
- if ( componentView ) {
261
- if ( ! this . currentRoute . interfaceType ) {
262
- this . currentRoute . interfaceType = this . getInterfaceTypeFromView ( componentView )
263
- this . routes . set ( this . currentRoute . path , this . currentRoute )
264
- }
259
+ this . getComponentView ( )
260
+ . then ( ( componentView ) => {
261
+ if ( componentView && this . currentRoute ) {
262
+ if ( ! this . currentRoute . interfaceType ) {
263
+ this . currentRoute . interfaceType =
264
+ this . getInterfaceTypeFromView ( componentView )
265
+ this . routes . set ( this . currentRoute . path , this . currentRoute )
266
+ }
265
267
266
- if ( this . currentRoute . interfaceType === 'STRING' ) {
267
- componentView = this . transformLinksInStringComponent ( componentView )
268
- }
269
- this . target . appendChild ( componentView )
270
- this . currentRoute . isComponentClass && this . currentRoute . component . afterRender ( )
271
- }
268
+ if ( this . currentRoute . interfaceType === 'STRING' ) {
269
+ componentView = this . transformLinksInStringComponent ( componentView )
270
+ }
271
+ this . target . appendChild ( componentView )
272
+ this . currentRoute . isComponentClass &&
273
+ this . currentRoute . component . afterRender ( )
274
+ }
275
+ } )
276
+ . catch ( ( error ) => {
277
+ console . warn ( 'getComponentView::promise rejected' , error )
278
+ } )
272
279
}
273
280
}
274
281
@@ -305,15 +312,39 @@ export default class App {
305
312
if ( this . currentRoute ) {
306
313
if ( this . currentRoute . isComponentClass ) {
307
314
this . updateComponentRouteData ( )
308
- this . currentRoute . component . beforeRender ( )
309
- return this . currentRoute . component . render ( )
310
- } else {
311
- return this . currentRoute . component . call (
315
+ const beforeRenderFn = this . currentRoute . component . beforeRender ( )
316
+
317
+ if ( beforeRenderFn instanceof Promise ) {
318
+ return this . runRenderWhenReady ( this . currentRoute , beforeRenderFn )
319
+ }
320
+
321
+ return Promise . resolve ( this . currentRoute . component . render ( ) )
322
+ }
323
+
324
+ return Promise . resolve (
325
+ this . currentRoute . component . call (
312
326
this . currentRoute . component ,
313
327
this . currentRoute . props
314
328
)
315
- }
329
+ )
316
330
}
331
+
332
+ return Promise . reject ( new Error ( 'getComponentView::promise not resolved' ) )
333
+ }
334
+
335
+ /**
336
+ * Run render function when asynchronous before render is resolved
337
+ * @param currentRoute Current route
338
+ * @param beforeRenderFn Before render promise
339
+ * @returns The render content
340
+ */
341
+ runRenderWhenReady ( currentRoute : RouteData , beforeRenderFn : Promise < unknown > ) {
342
+ return Promise . resolve ( beforeRenderFn ) . then ( ( ) => {
343
+ // Check is route has changed before the promise resolution
344
+ if ( this . currentRoute && this . currentRoute . path === currentRoute . path ) {
345
+ return currentRoute . component . render ( )
346
+ }
347
+ } )
317
348
}
318
349
319
350
/**
0 commit comments