JS Angular 服務器端渲染應用設置渲染超時時間
我們用 setTimeout
模擬一個需要 5 秒鐘才能完成調用的 API:
const express = require('express'); const app = express(); app.get('/api/fast', (req, res) => { console.log('fast endpoint hit'); res.send({response: 'fast'}); }); app.get('/api/slow', (req, res) => { setTimeout(() => { console.log('slow endpoint hit'); res.send({response: 'slow'}); }, 5000); }); app.listen(8081, () => { console.log('Listening'); });
然後新建一個 Angular service,調用這個 /api/slow
:
import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { Observable } from 'rxjs'; @Injectable({ providedIn: 'root' }) export class CustomService { constructor(private http: HttpClient) {} public getFast(): Observable<any> { return this.http.get<any>('http://localhost:8081/api/fast'); } public getSlow(): Observable<any> { return this.http.get<any>('http://localhost:8081/api/slow'); } }
在服務器端渲染模式下,等待這個 API 調用的返回,至少需要花費 5 秒鐘。我們可以給這個 API 調用設置一個超時機制。如果服務器端渲染時超過我們指定的超時間隔,還沒有得到 API 響應,我們就放棄這次 API 調用,讓其在客戶端渲染模式下繼續進行。
我們使用 RouteResolver 來實現。
從 Angular route 框架導入 router
:
import { Resolve } from '@angular/router';
從 Angular common 開發包導入 Angular 運行環境監測的 API:
import { isPlatformBrowser } from '@angular/common';
導入 injection token,獲得當前運行的 platform id:
import { Injectable, Inject, PLATFORM_ID } from '@angular/core';
新建一個 service class:
import { Injectable, Inject, PLATFORM_ID } from '@angular/core'; import { Resolve } from '@angular/router'; import { Observable, timer } from 'rxjs'; import { isPlatformBrowser } from '@angular/common'; import { CustomService } from './custom.service'; import { takeUntil } from 'rxjs/operators'; @Injectable({ providedIn: 'root' }) export class SlowComponentResolverService implements Resolve<any> { constructor(private service: CustomService, @Inject(PLATFORM_ID) private platformId: any) { } public resolve(): Observable<any> { if (isPlatformBrowser(this.platformId)) { return this.service.getSlow(); }
如果當前應用運行於瀏覽器端,上圖的 isPlatformBrowser(this.platformId)
返回 true,因此直接調用慢速 API.
否則創建一個 Observable,500 毫秒後發射值:
const watchdog: Observable<number> = timer(500);
我們將這個 watchDog Observable 通過 pipe 設置到 this.service.getSlow 的下遊。這樣,如果 this.service.getSlow() 返回的 Observable 在 500 毫秒之內不 emit 值的話,watchdog 就會向 Component push null 值,否則,API 的真實 response 會推送給 Component.
我們需要更新應用相關的 routing 代碼來消費這個 Resolver.
給 slowComponent 分配一個 resolver:
const routes: Routes = [ {path: '', redirectTo: 'fast', pathMatch: 'full'}, {path: 'fast', component: FastComponent}, {path: 'slow', component: SlowComponent, resolve: {response: SlowComponentResolverService}} ];
在 slowComponent 的實現代碼裡,從分配的 Route resolver 裡讀取 API response 數據:
import { Component } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; @Component({ selector: 'app-slow', template: ` <p> Response is: {{response | json}} </p> `, styles: [] }) export class SlowComponent { public response: any = this.router.snapshot.data.response; constructor(private router: ActivatedRoute) {} }
註意這裡並沒有直接訪問 Route Resolver:this.router.snapshot.data.response
當 API 在 500 毫秒之內返回時,所有的 slowComponent 源代碼都由服務器端生成:
當 API 500 毫秒未能成功返回數據,則客戶端會再次調用該 API,然後在客戶端完成渲染:
到此這篇關於JS Angular 服務器端渲染應用設置渲染超時時間的文章就介紹到這瞭,更多相關JS Angular 服務器端渲染內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- 從 Angular Route 中提前獲取數據的方法詳解
- 在Angular項目使用socket.io實現通信的方法
- 詳解Angular之路由基礎
- 詳解Angular路由之子路由
- Rxjs 中處理錯誤和抓取錯誤的代碼案例