Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/387.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript RxJS使用第一个流的输出运行第二个流_Javascript_Angular_Rxjs_Observable - Fatal编程技术网

Javascript RxJS使用第一个流的输出运行第二个流

Javascript RxJS使用第一个流的输出运行第二个流,javascript,angular,rxjs,observable,Javascript,Angular,Rxjs,Observable,我有一个服务,它决定了位置,它被写为可观察的 import { Injectable } from '@angular/core'; import { Observable } from 'rxjs'; const GEOLOCATION_ERRORS = { 'errors.location.unsupportedBrowser': 'Browser does not support location services', 'errors.location.permissio

我有一个服务,它决定了位置,它被写为可观察的

import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';

const GEOLOCATION_ERRORS = {
    'errors.location.unsupportedBrowser': 'Browser does not support location services',
    'errors.location.permissionDenied': 'You have rejected access to your location',
    'errors.location.positionUnavailable': 'Unable to determine your location',
    'errors.location.timeout': 'Service timeout has been reached'
};

@Injectable()
export class GeolocationService {
    public getLocation(opts): Observable<any> {
        return Observable.create(observer => {
            if (window.navigator && window.navigator.geolocation) {
                window.navigator.geolocation.getCurrentPosition(
                    (position) => {
                        observer.next(position);
                        observer.complete();
                    },
                    (error) => {
                        switch (error.code) {
                            case 1:
                                observer.error(GEOLOCATION_ERRORS['errors.location.permissionDenied']);
                                break;
                            case 2:
                                observer.error(GEOLOCATION_ERRORS['errors.location.positionUnavailable']);
                                break;
                            case 3:
                                observer.error(GEOLOCATION_ERRORS['errors.location.timeout']);
                                break;
                        }
                    }, opts);
            } else {
                observer.error(GEOLOCATION_ERRORS['errors.location.unsupportedBrowser']);
            }
        });
    }
}

export var GeolocationServiceInjectables: Array<any> = [
    { provide: GeolocationService, useClass: GeolocationService }
];
从'@angular/core'导入{Injectable};
从“rxjs”导入{Observable};
常量地理位置错误={
'errors.location.unsupportedBrowser':'Browser不支持位置服务',
“errors.location.permissionDenied':“您已拒绝访问您的位置”,
“errors.location.positionUnavailable':“无法确定您的位置”,
'错误.位置.超时':'已达到服务超时'
};
@可注射()
导出类地理定位服务{
公共getLocation(opts):可观察{
返回可观察的。创建(观察者=>{
if(window.navigator&&window.navigator.geolocation){
window.navigator.geolocation.getCurrentPosition(
(职位)=>{
观察员:下一个(位置);
observer.complete();
},
(错误)=>{
开关(错误代码){
案例1:
observer.error(地理位置错误['ERRORS.location.permissionDenied');
打破
案例2:
观察者错误(地理位置错误['ERRORS.location.positionUnavailable']);
打破
案例3:
observer.error(GEOLOCATION_ERRORS['ERRORS.location.timeout']);
打破
}
},opts);
}否则{
observer.error(地理位置错误['ERRORS.location.unsupportedBrowser']);
}
});
}
}
导出变量GeolocationServiceInjectables:数组=[
{provide:GeolocationService,useClass:GeolocationService}
];
然后在我的HttpService中,我想用location服务的输出构造查询URL

import { Observable } from 'rxjs/Observable';
import { Injectable, Inject } from '@angular/core';
import { Http, Response } from '@angular/http';
import { GeolocationService } from './location.service';
import { WeatherItem } from '../weather-item/weather-item.model';

export const OpenWeatherMap_API_KEY: string = 'SOME_API_KEY';
export const OpenWeatherMap_API_URL: string = 'http://api.openweathermap.org/data/2.5/forecast';

@Injectable()
export class HttpService {
    constructor(private http: Http,
        private geolocation: GeolocationService,
        @Inject(OpenWeatherMap_API_KEY) private apiKey: string,
        @Inject(OpenWeatherMap_API_URL) private apiUrl: string) {
    }

    prepaireQuery(): void {
        this.geolocation.getLocation({ enableHighAccuracy: false, maximumAge: 3 }).subscribe(
            (position) => {
                let params: string = [
                    `lat=${position.latitude}`,
                    `lon=${position.longitude}`,
                    `APPID=${this.apiKey}`,
                ].join('&');
              //  return `${this.apiUrl}?${params}`;
            }
        );

    }

    getWeather(): Observable<WeatherItem[]> {
        return this.http.get(/*there should be the url*/)
            .map((response: Response) => {
                return (<any>response.json()).items.map(item => {
                    const city = {
                        city: item.city.name,
                        country: item.city.country,
                    }
                    return item.list.map(entity => {
                        return new WeatherItem({
                            temp: entity.main.temp,
                            temMin: entity.main.temp_min,
                            temMax: entity.main.temp_max,
                            weatherCond: entity.weather.main,
                            description: entity.weather.description,
                            windSpeed: entity.wind.speed,
                            icon: entity.weather.icon,
                            city,
                        })
                    })
                })
            })
    }
}
export var HttpServiceInjectables: Array<any> = [
    { provide: HttpService, useClass: HttpService },
    { provide: OpenWeatherMap_API_KEY, useValue: OpenWeatherMap_API_KEY },
    { provide: OpenWeatherMap_API_URL, useValue: OpenWeatherMap_API_KEY }
];
从'rxjs/Observable'导入{Observable};
从“@angular/core”导入{Injectable,injection};
从'@angular/Http'导入{Http,Response};
从“./location.service”导入{GeolocationService};
从“../weather item/weather item.model”导入{WeatherItem};
export const OpenWeatherMap_API_KEY:string='SOME_API_KEY';
export const OpenWeatherMap\u API\u URL:string='10〕http://api.openweathermap.org/data/2.5/forecast';
@可注射()
导出类HttpService{
构造函数(私有http:http,
私人地理定位:地理定位服务,
@注入(OpenWeatherMap_API_密钥)私有apiKey:string,
@Inject(OpenWeatherMap\uAPI\uURL)私有apiUrl:string){
}
prepairequiry():void{
this.geolocation.getLocation({enableHighAccurance:false,maximumAge:3})。订阅(
(职位)=>{
让参数:字符串=[
`纬度=${position.latitude}`,
`lon=${position.longitude}`,
`APPID=${this.apiKey}`,
].加入(“&”);
//返回`${this.apirl}?${params}`;
}
);
}
getWeather():可观察{
返回此.http.get(/*应该有url*/)
.map((响应:响应)=>{
return(response.json()).items.map(item=>{
康斯特市={
城市:item.city.name,
国家:item.city.country,
}
返回item.list.map(实体=>{
返回新的天气项目({
temp:entity.main.temp,
temMin:entity.main.temp_min,
temMax:entity.main.temp_max,
weatherCond:entity.weather.main,
description:entity.weather.description,
风速:entity.wind.speed,
图标:entity.weather.icon,
城市
})
})
})
})
}
}
导出变量HttpServiceInjectables:数组=[
{provide:HttpService,useClass:HttpService},
{提供:OpenWeatherMap\u API\u KEY,使用值:OpenWeatherMap\u API\u KEY},
{提供:OpenWeatherMap\uAPI\uURL,使用值:OpenWeatherMap\uAPI\uKey}
];

问题是如何在执行请求之前获取URL。我见过使用unsubscribe()的解决方案,但我认为它们都不太好。我考虑过merge(),但我不确定这是否是我真正想要的

您可能正在寻找RxJs的
mergeMap
操作符

mergeMap
所做的是自动订阅源可观察对象,然后让您在内部可观察对象中处理其结果,最后将输出平坦化

在本例中,您调用
firstUrl
,并在第二次调用
secondUrl
时使用从该请求获得的结果:

this.http.get(`{firstUrl}`)
   .mergeMap(res => this.http.get(`{secondUrl}/{res.json()}`))
   .subscribe(...)

我没有为你的代码做具体的说明,因为我不确定你到底想做什么。但我希望这会在路上帮助你

您可能正在寻找RxJs的
mergeMap
操作符

mergeMap
所做的是自动订阅源可观察对象,然后让您在内部可观察对象中处理其结果,最后将输出平坦化

在本例中,您调用
firstUrl
,并在第二次调用
secondUrl
时使用从该请求获得的结果:

this.http.get(`{firstUrl}`)
   .mergeMap(res => this.http.get(`{secondUrl}/{res.json()}`))
   .subscribe(...)

我没有为你的代码做具体的说明,因为我不确定你到底想做什么。但我希望这会在路上帮助你

这可以使用
map
/
flatMap
组合完成:

getWeather(): Observable<WeatherItem[]> {
    return this.geolocation.getLocation({ enableHighAccuracy: false, maximumAge: 3 })
        .map((position) => {
            let params: string = [
                `lat=${position.latitude}`,
                `lon=${position.longitude}`,
                `APPID=${this.apiKey}`,
            ].join('&');
          return `${this.apiUrl}?${params}`;
        })
        .flatMap(url => this.http.get(url)
        .map((response: Response) => {
            return (<any>response.json()).items.map(item => {
                const city = {
                    city: item.city.name,
                    country: item.city.country,
                }
                return item.list.map(entity => {
                    return new WeatherItem({
                        temp: entity.main.temp,
                        temMin: entity.main.temp_min,
                        temMax: entity.main.temp_max,
                        weatherCond: entity.weather.main,
                        description: entity.weather.description,
                        windSpeed: entity.wind.speed,
                        icon: entity.weather.icon,
                        city,
                    })
                })
            })
        })
}
getWeather():可观察{
返回this.geolocation.getLocation({enableHighAccurance:false,maximumAge:3})
.map((位置)=>{