我正在处理离子/角和RXJS可观察物。
我正在尝试使用Rxjs observables重构我的代码,并且我有下一个代码:
ionViewWillEnter() {
if (this.platform.is('core') || this.platform.is('mobileweb')) {
this.lat = 37.3675506;
this.lng = -6.0452695;
this.printMap();
} else {
if (this.platform.is('android')) {
this.tryGeolocation();
} else if (this.platform.is('ios')) {
console.log("IOS")
}
}
}
如果要从android mobile访问用户,我应该检查:isLocationAuthorized,isLocationEnabled()以使用getCurrentPosition()获取当前位置,然后我必须在使用Observables forkjoin的位置打印Map。
问题是要检查方法是否返回promise,但我不知道如何链接此流程。
tryGeolocation是下一个:
async tryGeolocation() {
try {
if (await this.diagnostic.isLocationAuthorized()) {
if (await this.diagnostic.isLocationEnabled()) {
this.loading = this.loadingCtrl.create({
content: 'Localizando...',
dismissOnPageChange: true
});
this.loading.present();
const {coords} = await this.geolocation.getCurrentPosition();
this.lat = coords.latitude;
this.lng = coords.longitude;
this.loading.dismiss();
alert(this.lat);
alert(this.lng);
this.printMap();
} else {
console.log("error1")
}
} else {
console.log("error2")
}
} catch (e) {
console.log('Error getting location', e);
}
}
printMap() {
let obs1 = this._sp.getLocationsByPosition(this.lat, this.lng);
let obs2 = this._sp.getUserFavoriteLocations2();
this.subscription = forkJoin([obs1, obs2]).subscribe(results => {
this.allLocations = results[0];
this.myLocations = results[1];
this.allLocations = this.allLocations.filter(item => !this.myLocations.some(other => item.id.sid_location === other.id.sid_location && item.id.bid_environment === other.id.bid_environment));
this.map = new google.maps.Map(this.mapElement.nativeElement, {
zoom: 13,
center: {lat: parseFloat(this.lat), lng: parseFloat(this.lng)},
zoomControl: true,
draggable: true
});
new google.maps.Marker({
position: {lat: parseFloat(this.lat), lng: parseFloat(this.lng)},
map: this.map,
icon: {
url: "https://maps.gstatic.com/mapfiles/api-3/images/spotlight-poi2_hdpi.png"
}
});
this.printMarkers();
});
}
我已经尝试过将诺言转换为像这样的可观察对象:
let obs1 = Observable.fromPromise(this.diagnostic.isLocationAuthorized());
let obs2 = Observable.fromPromise(this.diagnostic.isLocationEnabled());
let obs3 = Observable.fromPromise(this.geolocation.getCurrentPosition());
obs1.flatMap(() => obs2)
.flatMap(() => obs3)
.subscribe(coords => {
console.log(coords);
//CALL TO printMap?
})
有人可以帮助我实现重构我的代码的流程吗?
提前谢谢
答案 0 :(得分:0)
fromPromise
已过时,它不再出现在documentation中。使用from
to get an observable from a promise。
import { from } from 'rxjs';
let obs1 = from(this.diagnostic.isLocationAuthorized());
let obs2 = fromPromise(this.diagnostic.isLocationEnabled());
let obs3 = fromPromise(this.geolocation.getCurrentPosition());
但是请考虑一下是否值得在您的用例中使用。 This answer would help you to decide。
事实证明,您可以将async-await与observables混合使用,但这并不意味着它将适合您的用例。 (请谨慎使用此代码)
import { defer } from 'rxjs';
defer(async function() {
const a = await promiseDelay(1000).then(() => 1);
const b = a + await promiseDelay(1000).then(() => 2);
return a + b + await promiseDelay(1000).then(() => 3);
})
.subscribe(x => console.log(x)) // logs 7
但请不要忘记异步等待和可观察对象 do not work together。 Defer docs。
答案 1 :(得分:0)
您可以使用 from
和 combineLatest
对您的承诺链进行 rxjs 化。我在这里发布了一个 stackblitz 示例 - https://stackblitz.com/edit/rxjs-jnrj37?devtoolsheight=60
基本上是这样的:
import { combineLatest, from, of } from "rxjs";
import { map } from "rxjs/operators";
const promiseMaker = timeInMS =>
new Promise((resolve, reject) => {
setTimeout(() => {
console.log("promise done");
resolve("foo");
}, timeInMS);
});
const promise1$ = from(promiseMaker(300));
const promise2$ = from(promiseMaker(500));
const promise3$ = from(promiseMaker(800));
combineLatest(promise1$, promise2$, promise3$).subscribe(() =>
console.log("Ready!!!")
);
如果 promise 相互依赖,那么您可以使用 combineLatest
或 switchMap
代替 mergeMap
并根据需要将它们链接起来