如何在 Ionic 3 中执行多个异步操作并在完成所有操作后关闭加载器?
How to perform multiple asynchronous actions in Ionic 3 and dismiss a loader after everything is done?
我正在开发一个 Ionic 3 应用程序,它可以选择按需缓存文章内容列表。我正在使用 Storage
,它使用 promises 进行操作。
我的代码如下:
文章-service.ts
getArticleFullData(articleId: number) {
let appSettings = this.appSettingsService.getSettings();
let params = this.utilsService.serializeQueryParams(appSettings);
let url = `${this.apiBasePath}Article/GetArticleFullData?articleId=${articleId}&${params}`;
this.loggingService.logInfo("Getting article full data from url " + url);
return this.http.get(url)
.map(res => res.json());
}
文章缓存-service.ts
// saves a single article to the cache
private saveToCache(articleId: number): Observable<any> {
let key = articleId;
let obs = this.articleService.getArticleFullData(key);
obs.subscribe(data => {
this.storage.set(this.GetArticleFullKey(key), data as ArticleFullData);
},
err => {
this.loggingService.logError("Failed to cache data for article: " + key);
}
);
return obs;
}
// tries to cache a list of article in the cache
// avoids overwriting the data, if exists
public saveArticleDataToCache(articles: ArticleBriefData[]): Observable<{}[]> {
var obsArray = [];
for (let article of articles) {
let key = this.GetArticleFullKey(article.ArticleId);
this.storage.get(key)
.then(data => {
console.log("Storage data for article " + key, data);
if (!data) {
obsArray.push(this.saveToCache(article.ArticleId));
}
})
.catch(err => {
this.loggingService.logError("Failed to check storage for key " + key, err);
});
}
var ret = Observable.forkJoin(obsArray);
return ret;
}
包含加载程序的代码
this.loadingCtrl.create({ content: "Caching data. Please wait..." });
this.loadingCtrl.present();
var all = this.articleCacheService.saveArticleDataToCache(this.articles);
var subscr = all
.toPromise()
.then(data => {
console.log("All data: ", data);
this.loadingCtrl.dismiss();
this.loggingService.logInfo("Successfully cached articles ");
})
.catch(err => {
this.loadingCtrl.dismiss();
this.loggingService.logError("Failed to cache data: ", JSON.stringify(err));
}
);
缓存进程正确执行,但then
代码立即执行(data
是undefined
)
我也试过subscribe
的方法,但是subscribe
里面的代码好像没有被执行(不过缓存是正确执行的):
var all = this.articleCacheService.saveArticleDataToCache(this.articles);
var subscr = all
.subscribe(data => {
console.log("All data: ", data);
this.loadingCtrl.dismiss();
this.loggingService.logInfo("Successfully cached articles ");
},
err => {
this.loadingCtrl.dismiss();
this.loggingService.logError("Failed to cache data: ", JSON.stringify(err));
}
);
我显然不能正常使用这里的 Observable
s。
问题:如何在 Ionic 3 中执行多个异步操作并在完成所有操作后关闭加载器?
您可以使用 forkjoin
轻松完成。
注:我已经提取了我的代码app.So根据你的用途改一下case.If你正在使用 RXJS 5.5.2
然后根据最新 changes here
更改 imports
import { Observable } from "rxjs/Observable";
import 'rxjs/add/observable/forkJoin'
let myTopicApi = this.getMytopic();
let myarticlApi = this.getMyArticles();
let myPicksAPi = this.getMyPicks();
Observable.forkJoin([myTopicApi, myarticlApi, myPicksAPi])
.subscribe(res => {
this.arrangeMytopics(res[0]);
this.arrangeMyArticles(res[1]);
this.arrangeMyPicks(res[2]);
if (loading) { loading.dismiss(); loading = null; }//here you can dismiss your loader
},
error => { if (loading) { loading.dismiss(); loading = null; }//here you can dismiss your loader },
() => { });
getMytopic() {
return this.topicSer.getMyTopics().map((res: any) => res.json()).map((res: any) => res = res.categories)
.catch((err: any) => { })
}
Sampath
的回答帮我找到了问题所在。我做错的是我构建 Observable
数组的方式(它在 forkJoin
中使用):在 Promise
[=] 的 then
函数中推入列表 return由存储获取。
修复此问题后我的代码还包括检查项目是否存在(以避免 HTTP 调用和重置存储数据):
文章-service.ts
getArticleFullData(articleId: number) {
let appSettings = this.appSettingsService.getSettings();
let params = this.utilsService.serializeQueryParams(appSettings);
let url = `${this.apiBasePath}Article/GetArticleFullData?articleId=${articleId}&${params}`;
return this.http.get(url)
.map(res => res.json());
}
文章缓存-service.ts
我正在使用 flatMap
链接 Observable
通过检查存储是否已经有密钥和实际提取获得。如果数据存在,我 return 一个空的 Observable
实际取消进程。
private saveToCache(articleId: number): Observable<any> {
let key = this.GetArticleFullKey(articleId);
let storageObs = Observable.fromPromise(this.storage.get(key));
let getArticleObs = this.articleService.getArticleFullData(articleId);
let obs = storageObs.flatMap(data => {
if (!data)
return getArticleObs;
else
return Observable.of(null);
});
obs.subscribe(data => {
if (data)
this.storage.set(key, data as ArticleFullData);
},
err => {
this.loggingService.logError("Failed to cache data for article: " + articleId);
}
);
return obs;
}
public saveArticleDataToCache(articles: ArticleBriefData[]): Observable<{}[]> {
let obsArray = [];
for (let article of articles) {
let obs = this.saveToCache(article.ArticleId);
obsArray.push(obs);
}
let ret = Observable.forkJoin(obsArray);
return ret;
}
实际订阅
onCacheRefresh() {
// articles are not loaded for some reason
if (!this.articles)
return;
this.loadingCtrl.create({ content: "Caching data. Please wait..." });
this.loadingCtrl.present();
let all = this.articleCacheService.saveArticleDataToCache(this.articles);
let subscr = all
.subscribe(data => {
console.log("All data: ", data);
this.loadingCtrl.dismiss();
this.loggingService.logInfo("Successfully cached articles ");
},
err => {
this.loadingCtrl.dismiss();
this.loggingService.logError("Failed to cache data: ", JSON.stringify(err));
}
);
}
我正在开发一个 Ionic 3 应用程序,它可以选择按需缓存文章内容列表。我正在使用 Storage
,它使用 promises 进行操作。
我的代码如下:
文章-service.ts
getArticleFullData(articleId: number) {
let appSettings = this.appSettingsService.getSettings();
let params = this.utilsService.serializeQueryParams(appSettings);
let url = `${this.apiBasePath}Article/GetArticleFullData?articleId=${articleId}&${params}`;
this.loggingService.logInfo("Getting article full data from url " + url);
return this.http.get(url)
.map(res => res.json());
}
文章缓存-service.ts
// saves a single article to the cache
private saveToCache(articleId: number): Observable<any> {
let key = articleId;
let obs = this.articleService.getArticleFullData(key);
obs.subscribe(data => {
this.storage.set(this.GetArticleFullKey(key), data as ArticleFullData);
},
err => {
this.loggingService.logError("Failed to cache data for article: " + key);
}
);
return obs;
}
// tries to cache a list of article in the cache
// avoids overwriting the data, if exists
public saveArticleDataToCache(articles: ArticleBriefData[]): Observable<{}[]> {
var obsArray = [];
for (let article of articles) {
let key = this.GetArticleFullKey(article.ArticleId);
this.storage.get(key)
.then(data => {
console.log("Storage data for article " + key, data);
if (!data) {
obsArray.push(this.saveToCache(article.ArticleId));
}
})
.catch(err => {
this.loggingService.logError("Failed to check storage for key " + key, err);
});
}
var ret = Observable.forkJoin(obsArray);
return ret;
}
包含加载程序的代码
this.loadingCtrl.create({ content: "Caching data. Please wait..." });
this.loadingCtrl.present();
var all = this.articleCacheService.saveArticleDataToCache(this.articles);
var subscr = all
.toPromise()
.then(data => {
console.log("All data: ", data);
this.loadingCtrl.dismiss();
this.loggingService.logInfo("Successfully cached articles ");
})
.catch(err => {
this.loadingCtrl.dismiss();
this.loggingService.logError("Failed to cache data: ", JSON.stringify(err));
}
);
缓存进程正确执行,但then
代码立即执行(data
是undefined
)
我也试过subscribe
的方法,但是subscribe
里面的代码好像没有被执行(不过缓存是正确执行的):
var all = this.articleCacheService.saveArticleDataToCache(this.articles);
var subscr = all
.subscribe(data => {
console.log("All data: ", data);
this.loadingCtrl.dismiss();
this.loggingService.logInfo("Successfully cached articles ");
},
err => {
this.loadingCtrl.dismiss();
this.loggingService.logError("Failed to cache data: ", JSON.stringify(err));
}
);
我显然不能正常使用这里的 Observable
s。
问题:如何在 Ionic 3 中执行多个异步操作并在完成所有操作后关闭加载器?
您可以使用 forkjoin
轻松完成。
注:我已经提取了我的代码app.So根据你的用途改一下case.If你正在使用 RXJS 5.5.2
然后根据最新 changes here
imports
import { Observable } from "rxjs/Observable";
import 'rxjs/add/observable/forkJoin'
let myTopicApi = this.getMytopic();
let myarticlApi = this.getMyArticles();
let myPicksAPi = this.getMyPicks();
Observable.forkJoin([myTopicApi, myarticlApi, myPicksAPi])
.subscribe(res => {
this.arrangeMytopics(res[0]);
this.arrangeMyArticles(res[1]);
this.arrangeMyPicks(res[2]);
if (loading) { loading.dismiss(); loading = null; }//here you can dismiss your loader
},
error => { if (loading) { loading.dismiss(); loading = null; }//here you can dismiss your loader },
() => { });
getMytopic() {
return this.topicSer.getMyTopics().map((res: any) => res.json()).map((res: any) => res = res.categories)
.catch((err: any) => { })
}
Sampath
的回答帮我找到了问题所在。我做错的是我构建 Observable
数组的方式(它在 forkJoin
中使用):在 Promise
[=] 的 then
函数中推入列表 return由存储获取。
修复此问题后我的代码还包括检查项目是否存在(以避免 HTTP 调用和重置存储数据):
文章-service.ts
getArticleFullData(articleId: number) {
let appSettings = this.appSettingsService.getSettings();
let params = this.utilsService.serializeQueryParams(appSettings);
let url = `${this.apiBasePath}Article/GetArticleFullData?articleId=${articleId}&${params}`;
return this.http.get(url)
.map(res => res.json());
}
文章缓存-service.ts
我正在使用 flatMap
链接 Observable
通过检查存储是否已经有密钥和实际提取获得。如果数据存在,我 return 一个空的 Observable
实际取消进程。
private saveToCache(articleId: number): Observable<any> {
let key = this.GetArticleFullKey(articleId);
let storageObs = Observable.fromPromise(this.storage.get(key));
let getArticleObs = this.articleService.getArticleFullData(articleId);
let obs = storageObs.flatMap(data => {
if (!data)
return getArticleObs;
else
return Observable.of(null);
});
obs.subscribe(data => {
if (data)
this.storage.set(key, data as ArticleFullData);
},
err => {
this.loggingService.logError("Failed to cache data for article: " + articleId);
}
);
return obs;
}
public saveArticleDataToCache(articles: ArticleBriefData[]): Observable<{}[]> {
let obsArray = [];
for (let article of articles) {
let obs = this.saveToCache(article.ArticleId);
obsArray.push(obs);
}
let ret = Observable.forkJoin(obsArray);
return ret;
}
实际订阅
onCacheRefresh() {
// articles are not loaded for some reason
if (!this.articles)
return;
this.loadingCtrl.create({ content: "Caching data. Please wait..." });
this.loadingCtrl.present();
let all = this.articleCacheService.saveArticleDataToCache(this.articles);
let subscr = all
.subscribe(data => {
console.log("All data: ", data);
this.loadingCtrl.dismiss();
this.loggingService.logInfo("Successfully cached articles ");
},
err => {
this.loadingCtrl.dismiss();
this.loggingService.logError("Failed to cache data: ", JSON.stringify(err));
}
);
}