У меня очень широкий, но простой вопрос относительно HTTP-запросов через Angular. У меня есть приложение Ionic, использующее HTTP-запросы Angular, но я не уверен, что максимально использую то, что Angular может предложить для скорости и эффективности. Мой текущий код для моего запроса POST:
страница отправки данных .ts:
//calls provider function
this.stemAPI.submitBOLData(this.submitAllData,this.reap.token).then((result) =>{
//API response handled here
}, (err) => {
//Error handled here
});поставщик .ts
import { HttpClient,HttpHeaders } from '@angular/common/http';
import { Injectable } from '@angular/core';
// import { Observable } from 'rxjs/Observable';
// import { interval } from 'rxjs/observable/interval';
// import { of } from 'rxjs/observable/of';
// import { _throw } from 'rxjs/observable/throw';
// import { mergeMap, retry } from 'rxjs/operators';
import { retry } from 'rxjs/operators';
@Injectable()
constructor(public http: HttpClient) {}
export class StemApiProvider {
//POST form submitBOL
submitBOLData(data,authToken){
//console.info(data);
const httpOptions = {
headers: new HttpHeaders({
'Accept': 'application/json, text/plain',
'Content-Type': 'application/json',
'Authorization': authToken
})
};
return new Promise((resolve, reject) => {
this.http.post(this.apisubmitbolUrl, JSON.stringify(data), httpOptions)
.subscribe(res=> {
resolve(res);
}, (err) => {
reject(err);
});
});
}
}Звонок работает нормально, но я знаю, что можно добавить больше эффективности. Кроме того, я знаю, что пакет rxjs предлагает такие функции, как «повторная попытка» в случае сбоя вызова, но я не уверен, как именно это можно реализовать.
Основная причина этого вопроса заключается в том, что мои клиенты потенциально будут использовать приложение в областях, где нет лучшего сотового соединения, поэтому вызовы API могут занять больше времени, и я, если соединение произойдет, я хочу знать, какие инструменты я можно использовать, чтобы предоставить пользователю другие возможности.
Обновлено: package.json
{
"name": "Test Project",
"version": "0.6.0",
"author": "",
"homepage": "",
"private": true,
"scripts": {
"clean": "ionic-app-scripts clean",
"build": "ionic-app-scripts build",
"lint": "ionic-app-scripts lint",
"ionic:build": "ionic-app-scripts build",
"ionic:serve": "ionic-app-scripts serve"
},
"dependencies": {
"@angular/animations": "5.2.10",
"@angular/common": "5.2.10",
"@angular/compiler": "5.2.10",
"@angular/compiler-cli": "5.2.10",
"@angular/core": "5.2.10",
"@angular/forms": "5.2.10",
"@angular/http": "5.2.10",
"@angular/platform-browser": "5.2.10",
"@angular/platform-browser-dynamic": "5.2.10",
"@ionic-native/app-version": "^4.15.0",
"@ionic-native/camera": "^4.15.0",
"@ionic-native/core": "4.11.0",
"@ionic-native/device": "^4.15.0",
"@ionic-native/file": "^4.15.0",
"@ionic-native/file-transfer": "^4.15.0",
"@ionic-native/geolocation": "^4.15.0",
"@ionic-native/ionic-webview": "^5.0.0-beta.21",
"@ionic-native/network": "^4.15.0",
"@ionic-native/splash-screen": "4.7.0",
"@ionic-native/status-bar": "4.7.0",
"@ionic/pro": "^2.0.3",
"@ionic/storage": "^2.2.0",
"angular2-signaturepad": "^2.8.0",
"cordova-android": "7.1.1",
"cordova-browser": "5.0.3",
"cordova-ios": "4.5.5",
"cordova-plugin-app-version": "^0.1.9",
"cordova-plugin-camera": "^4.0.3",
"cordova-plugin-device": "^2.0.2",
"cordova-plugin-file": "6.0.1",
"cordova-plugin-file-transfer": "1.7.1",
"cordova-plugin-geolocation": "^4.0.1",
"cordova-plugin-ionic": "5.2.5",
"cordova-plugin-ionic-keyboard": "^2.1.3",
"cordova-plugin-ionic-webview": "^2.2.0",
"cordova-plugin-network-information": "^2.0.1",
"cordova-plugin-splashscreen": "^5.0.2",
"cordova-plugin-webview": "0.0.1",
"cordova-plugin-whitelist": "^1.3.3",
"cordova-sqlite-storage": "2.4.0",
"ionic-angular": "^3.9.2",
"ionic-select-searchable": "^2.10.0",
"ionic-selectable": "^3.0.3",
"ionicons": "3.0.0",
"rxjs": "5.5.11",
"sw-toolbox": "3.6.0",
"ts-md5": "^1.2.4",
"ws": "^3.3.3",
"zone.js": "0.8.26"
},
"devDependencies": {
"@ionic/app-scripts": "3.2.0",
"typescript": "~2.6.2"
},
"description": "An Ionic project",
"cordova": {
"plugins": {
"cordova-plugin-geolocation": {
"GEOLOCATION_USAGE_DESCRIPTION": "To locate you"
},
"cordova-plugin-device": {},
"cordova-plugin-app-version": {},
"cordova-plugin-camera": {},
"cordova-plugin-whitelist": {},
"cordova-plugin-splashscreen": {},
"cordova-plugin-ionic-keyboard": {},
"cordova-plugin-network-information": {},
"cordova-sqlite-storage": {},
"cordova-plugin-ionic-webview": {
"ANDROID_SUPPORT_ANNOTATIONS_VERSION": "27.+"
},
"cordova-plugin-ionic": {
"APP_ID": "",
"CHANNEL_NAME": "Master",
"UPDATE_METHOD": "background",
"UPDATE_API": "https://api.ionicjs.com",
"MAX_STORE": "2",
"MIN_BACKGROUND_DURATION": "30"
}
},
"platforms": [
"browser",
"ios",
"android"
]
}
}Как лучше всего реализовать это в моем текущем коде? Должен ли я заниматься всем в моем провайдере? Или я могу вернуть наблюдаемое обратно на свои страницы и обработать его там?
Ваш дизайн выглядит отлично. Обрабатывайте все обратно в своем компоненте, возвращая наблюдаемое от поставщика. Это облегчает непосредственное управление вашим видом. Верните тот же наблюдаемый объект, используя оператор rxjs map, вместо того, чтобы возвращать Promise, а затем подпишитесь на него из своего comp.
@AmitChigadani Спасибо за ваш отзыв, мы изучим и попробуем.





Прежде всего, я бы посоветовал вам использовать HttpClient, если вы используете Http. Он был представлен в Angular 4.3, и если вы его используете, вам не нужно делать .map(res => res.json()).
Сначала вам нужно добавить его HttpClientModule в массив imports вашего @NgModule.
import { HttpClientModule } from '@angular/common/http'
...
@NgModule({
...
imports: [..., HttpClientModule, ...],
...
})
Angular HttpClient возвращает Observable, а не Promise. Это дает вам преимущество, поскольку вы можете использовать такие операторы, как retryn раз, в случае сетевой ошибки, прежде чем показывать пользователю сообщение об ошибке.
Ваш код можно значительно реорганизовать под то же самое.
import 'rxjs/add/operator/retry';
...
submitBOLData(data, authToken) {
const httpOptions = {
headers: new HttpHeaders({
'Accept': 'application/json, text/plain',
'Content-Type': 'application/json',
'Authorization': authToken
})
};
return this.http.post(this.apisubmitbolUrl, data, httpOptions)
.retry(3); // This will retry 3 times in case there's an error
}
Где вы используете эту функцию:
this.stemAPI.submitBOLData(this.submitAllData, this.reap.token)
.subscribe(
res => { /* Do what you want with this error */ },
err => { /* Error handled here */ }
);
Вот Образец StackBlitz для вашего исх.
@AmitChigadani, HttpClient также доступен в Angular 4 и 5.
Да моя плохая !! Я только что это проверил. Доступно с 4.3. fullstack-developer.academy/angular-http-vs-httpclient
Теперь об этом стоит упомянуть, поскольку OP может использовать версию, предшествующую 4.3. Большое спасибо за ваш вклад :)
Спасибо, господа за отзыв, я постараюсь убедиться, что все работает, прежде чем отмечать как ответ. Кроме того, я обновляю вопрос своими зависимостями.
Итак, у меня был HttpClientModule, импортированный в мой app.module.ts, и я считаю, что использую его, я обновил свой провайдер, чтобы вы могли его увидеть. Хотя я думаю, что мой импорт для повторной попытки неверен
Ошибка при повторной попытке: «Свойство 'retry' не существует для типа 'Observable <Object>». Также функция ничего не возвращает.
@StephenRomero, моя беда, это не operators. Это operator в import "rxjs/add/operator/retry";. Я обновил ответ соответственно.
@SiddAjmera Ладно круто Работает отлично! По какой-то причине атом выдавал мне ошибки, но процесс прошел без проблем! Спасибо за помощь! Случайно есть ли другие операторы rxjs, которые я могу использовать для более эффективной обработки HTTP-запросов?
Вы можете попробовать
ObservableвместоPromise. Это рекомендуемый подход для HTTP-запросовAngular2+.