升级到 Angular 17 后,HttpClient 会缓存 http GET,然后只运行一次。
我预计会在网络中看到更多请求,但实际上它只显示第一个请求。 所有订阅 httpClient Observable 的第一个结果都显示相同。
我的应用程序配置
export const appConfig: ApplicationConfig = {
providers: [
provideRouter(
routes,
// withPreloading(PreloadAllModules),
// withDebugTracing(),
withComponentInputBinding(),
withRouterConfig({
paramsInheritanceStrategy: 'always',
})
),
importProvidersFrom(
BrowserModule,
LightboxModule,
OverlayModule,
SocketIoModule.forRoot(config),
MatDialogModule,
MatSnackBarModule,
provideFirebaseApp(() => initializeApp(environment.firebaseConfig)),
provideAuth(() => getAuth()),
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useFactory: HttpLoaderFactory,
deps: [HttpClient],
},
})
),
{ provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true },
provideAnimations(),
provideHttpClient(withInterceptorsFromDi(), withFetch()), // withInterceptors([relativePathInterceptor])
provideStore(),
provideEffects(),
isDevMode() ? provideStoreDevtools() : [],
provideClientHydration(),
],
};
这是我的 angular.json
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"newProjectRoot": "projects",
"projects": {
"sugar": {
"projectType": "application",
"schematics": {
"@schematics/angular:component": {
"style": "scss"
}
},
"root": "",
"sourceRoot": "src",
"prefix": "app",
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:application",
"options": {
"outputPath": "dist/sugar",
"index": "src/index.html",
"browser": "src/main.ts",
"polyfills": ["zone.js"],
"tsConfig": "tsconfig.app.json",
"inlineStyleLanguage": "scss",
"assets": ["src/favicon.ico", "src/assets"],
"styles": ["src/styles/styles.scss"],
"scripts": [],
"server": "src/main.server.ts",
"prerender": true,
"ssr": {
"entry": "server.ts"
}
},
"configurations": {
"production": {
"budgets": [
{
"type": "initial",
"maximumWarning": "500kb",
"maximumError": "1mb"
},
{
"type": "anyComponentStyle",
"maximumWarning": "2kb",
"maximumError": "4kb"
}
],
"outputHashing": "all"
},
"development2": {
"optimization": false,
"extractLicenses": false,
"sourceMap": true
}
},
"defaultConfiguration": "production"
},
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"configurations": {
"production": {
"buildTarget": "sugar:build:production"
},
"development": {
"buildTarget": "sugar:build:development2"
}
},
"defaultConfiguration": "development"
},
"extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n",
"options": {
"buildTarget": "sugar:build"
}
},
"test": {
"builder": "@angular-devkit/build-angular:karma",
"options": {
"polyfills": ["zone.js", "zone.js/testing"],
"tsConfig": "tsconfig.spec.json",
"inlineStyleLanguage": "scss",
"assets": ["src/favicon.ico", "src/assets"],
"styles": ["src/styles/styles.scss"],
"scripts": []
}
}
}
}
},
"cli": {
"analytics": "2d1ee5f9-3a66-4408-b599-05e081007ab2"
}
}
我的聊天.service.ts
import { HttpClient, HttpParams } from '@angular/common/http';
import { Injectable, } from '@angular/core';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { Conversation } from './interfaces/user.interface';
import { environment } from '../../../environments/environment';
@Injectable({
providedIn: 'root',
})
export class ChatService {
withCredentials = environment.withCredentials;
constructor(private http: HttpClient) {}
getInbox(): Observable<Array<Conversation>> {
// const url = `${environment.baseUrl}/api/chat/inbox?t=` + Date.now();
const url = `${environment.baseUrl}/api/chat/inbox`;
return this.http.get<Array<Conversation>>(url, {
withCredentials: this.withCredentials,
transferCache: false,
});
}
}
2种可能的解决方案
不要使用简单的
http.get().pipe()
或http.get().subscribe()
,而是使用combineLatest
,也许也可以在“第二个”forkJoin
上使用http.get()
,无论它在哪里发射!比如:combineLatest([this.http.get()]).subscribe(response => {...});
您可能已经注意到的解决方法:在请求网址中放置一个无用的可选请求参数,其值必须针对每个请求而更改,就像您的评论一样:
// const url =
${environment.baseUrl}/api/chat/inbox?t=
+ Date.now();
为了完整起见,我已经尝试了许多其他可能性,但以下方法均无效:
shareReplay
每个请求unsubscribe
, finalize
)ChangeDetectionStrategy