我开始使用RxJS,我不明白为什么在这个例子中我们需要使用像flatMap或的函数concatAll; 这里的数组数组在哪里?
var requestStream = Rx.Observable.just('https://api.github.com/users');
var responseMetastream = requestStream
.flatMap(function(requestUrl) {
return Rx.Observable.fromPromise(jQuery.getJSON(requestUrl));
});
responseMetastream.subscribe(url => {console.log(url)})
Run Code Online (Sandbox Code Playgroud)
如果有人可以直观地解释发生了什么,那将非常有帮助.
我过去经常发展很多,现在我转向RxJS.RxJS的文档没有提供关于如何从promise链到观察者序列的非常明确的例子.
例如,我通常用多个步骤编写promise链,比如
// a function that returns a promise
getPromise()
.then(function(result) {
// do something
})
.then(function(result) {
// do something
})
.then(function(result) {
// do something
})
.catch(function(err) {
// handle error
});
Run Code Online (Sandbox Code Playgroud)
我应该如何以RxJS风格重写这个承诺链?
我正在学习RxJS和Angular 2.假设我有一个带有多个异步函数调用的promise链,它取决于前一个的结果,如下所示:
var promiseChain = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(1);
}, 1000);
}).then((result) => {
console.log(result);
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(result + 2);
}, 1000);
});
}).then((result) => {
console.log(result);
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(result + 3);
}, 1000);
});
});
promiseChain.then((finalResult) => {
console.log(finalResult);
});
Run Code Online (Sandbox Code Playgroud)
我在不使用promise的情况下单独使用RxJS的尝试产生了以下结果:
var observableChain = Observable.create((observer) => {
setTimeout(() => {
observer.next(1);
observer.complete();
}, 1000);
}).flatMap((result) => {
console.log(result);
return Observable.create((observer) …Run Code Online (Sandbox Code Playgroud) 我尝试链接多个rx.js可观察量并传递数据.Flatmap应该是拟合运算符但是导入
import { Observable } from 'rxjs/Observable';
Run Code Online (Sandbox Code Playgroud)
找不到:
Error TS2339: Property 'flatmap' does not exist on type 'Observable<Coordinates>'
Run Code Online (Sandbox Code Playgroud)
5.0.0-beta.6使用rx.js的版本.
public getCurrentLocationAddress():Observable<String> {
return Observable.fromPromise(Geolocation.getCurrentPosition())
.map(location => location.coords)
.flatmap(coordinates => {
console.log(coordinates);
return this.http.request(this.geoCodingServer + "/json?latlng=" + coordinates.latitude + "," + coordinates.longitude)
.map((res: Response) => {
let data = res.json();
return data.results[0].formatted_address;
});
});
}
Run Code Online (Sandbox Code Playgroud) 我正在从Promise世界转向Observable世界.我通常用Promise做的一件事就是将一系列任务链接起来并使它们按顺序运行.例如,我有三个任务:printLog1()打印1到控制台,printLog23()打印2和3到控制台,printLog4()打印4.
当我想打印1-2-3-4时,我会写一个类似的承诺链
printLog1()
.then(() => {
printLog23();
})
.then(() => {
printLog4();
});
Run Code Online (Sandbox Code Playgroud)
现在我想要与Observable相同的功能,我可以将printLog()函数重写为Observable
printLog1 = Rx.Observabale.of(1).map((i) => console.log(i));
printLog23 = Rx.Observabale.of(2, 3).map((i) => console.log(i));
printLog4 = Rx.Observabale.of(4).map((i) => console.log(i));
Run Code Online (Sandbox Code Playgroud)
然后我有三个observable,它们向控制台发出不同的值.如何链接它们以便这三个可观察量按顺序运行并打印1-2-3-4?
什么是简化以下代码示例的方式?我找不到合适的操作员..任何人都可以举一个简短的例子吗?
this.returnsObservable1(...)
.subscribe(
success => {
this.returnsObservable2(...)
.subscribe(
success => {
this.returnsObservable3(...)
.subscribe(
success => {
...
},
Run Code Online (Sandbox Code Playgroud) 祝你圣诞快乐.
我的Angular 4应用程序不会等待.
我希望在我调用API之前放慢速度.
但我只是继续撞墙.
我在我的代码中使用了HttpInterceptor.
但是这些Observable只会爆炸.
不要太鄙视.
下面你会发现我的尝试.
export class ApiUrlInterceptor implements HttpInterceptor {
constructor(private http: Http) { }
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return Observable.create(observer => {
setTimeout(() => {
observer.next(true); //Not sure why I do this
const start = Date.now();
console.log(`Request for ${req.url}`);
return next.handle(req).do(event => {
if (event.type == HttpEventType.Response) {
const elapsed = Date.now() - start;
console.log(`Request for ${req.urlWithParams} took ${elapsed} ms.`);
}
});
}, 1000);
});
}
}
Run Code Online (Sandbox Code Playgroud)
结果是调用了API.
但没有安装调用者的结果
我的Observable似乎陷入困境.
我运气不好
我很清楚这是Angular中的反模式"不要等待随机数",而是构建你的应用程序,这样你就不需要了.我的实际用例是, …
wait rxjs angular-http-interceptors angular angular-httpclient
我是Rx的新手,我发现很难找到有关组成承诺的文档,以便第一个承诺的数据传递到第二个承诺,依此类推.这是三个非常基本的承诺,对数据的计算并不重要,只是必须使用先前承诺的数据来完成异步.
const p1 = () => Promise.resolve(1);
const p2 = x => { const val = x + 1; return Promise.resolve(val); };
const p3 = x => {
const isEven = x => x % 2 === 0;
return Promise.resolve(isEven(x));
};
Run Code Online (Sandbox Code Playgroud)
实现我正在谈论的构图的传统方式:
pl().then(p2).then(p3).then(console.log);
Run Code Online (Sandbox Code Playgroud)
我最喜欢的实现是Ramda的composeP和pipeP:
R.pipeP(p1, p2, p3, console.log)()
Run Code Online (Sandbox Code Playgroud)
似乎Rx可能能够非常流利地处理这种情况.但是,到目前为止我发现的最接近的是从RxJS到async(库)比较,这里https://github.com/Reactive-Extensions/RxJS/blob/master/doc/mapping/async/comparing.md:
var Rx = require('rx'),
fs = require('fs'),
path = require('path');
var file = path.join(__dirname, 'file.txt'),
dest = path.join(__dirname, 'file1.txt'),
exists = Rx.Observable.fromCallback(fs.exists),
rename = Rx.Observable.fromNodeCallback(fs.rename),
stat = Rx.Observable.fromNodeCallback(fs.stat);
exists(file) …Run Code Online (Sandbox Code Playgroud) 我已经看了很多资源,包括这个,这个和这个,但是我还没有达到预期的效果.
我要做的就是验证用户身份(使用firebase)然后进行身份验证后,加载他们的配置文件并将其存储在变量中,userProfile然后再加载下一页Dashboard:
我的登录服务:
public signinUser(user: User) {
this.af.auth.login({
email: user.email,
password: user.password
},
{
provider: AuthProviders.Password,
method: AuthMethods.Password
}
)
.then(
success => {
console.log('Authenticated');
this.getProfile().subscribe( // PROBLEM is here
profile => {
console.log(profile);
console.log('Profile Loaded');
this.router.navigate(['/dashboard']);
}
)
}
)
.catch(function (error) {
...
console.log('ERROR SIGNING USER IN');
}
Run Code Online (Sandbox Code Playgroud)
我的getProfile()方法:
public getProfile(): Observable<any> {
return this.af.database.object('/profiles/' + this.user.uid)
.flatMap(
profile => {
console.log('inside success');
console.log(profile);
this.userProfile = <User>profile;
console.log('getProfile …Run Code Online (Sandbox Code Playgroud) 我的Angular 2应用程序中有一个TypeScript函数,它返回一个Observable,将Web API数据推送回消费者,如下所示:
public getApiData(): Observable {
let readySource = Observable.from('no', 'no', 'ready');
let dataSource = http.get('api/getData');
// ... magic here
return chainedObservable;
}
Run Code Online (Sandbox Code Playgroud)
但是,http.get我不是像往常一样返回Observable ,而是需要将此HTTP调用链接到另一个readySourceObservable,该Observable指示API是否已准备好调用(它实际检查后台数据同步作业是否已完成).
如何将这两个Observable链接在一起,因此只有在readySource推送特定值(例如"ready" )后才会调用HTTP调用?
(注意,vanilla flatMap/selectMany在这里并不完全符合要求,因为我需要等到第一个Observable在调用第二个之前推送一个特定的值.)
我正在使用observables和flatMap运算符,我编写了一个方法,它调用并调用API并返回带有对象数组的observable.基本上我需要的是获取对象数组并处理每个对象,在处理完所有项之后,我想链接结果以使用我编写的另一个方法进行额外的API调用.以下代码可以满足我的需求:
this.apiService.getInformation('api-query', null).first().flatMap((apiData) => {
return apiData;
}).subscribe((dataObject) => {
this.processService.processFirstCall(dataObject);
}, null, () => {
this.apiService.getInformation('another-query', null).first().subscribe((anotherQueryData) => {
this.processService.processSecondCall(anotherQueryData);
});
});
Run Code Online (Sandbox Code Playgroud)
但是从我的角度来看,这种方法并不是最优的,我想使用flatMap来链接这些调用,但如果我执行以下操作
this.apiService.getInformation('api-query', null).first().flatMap((apiData) => {
return apiData;
}).flatMap((dataObject) => {
this.processService.processFirstCall(dataObject);
return [dataObject];
}).flatMap((value) => {
return this.apiService.getInformation('another-api-query', null).first();
}).subscribe((value) => {
this.processService.processSecondCall(value);
});
Run Code Online (Sandbox Code Playgroud)
第二个API调用对apiData对象数组上的每个项执行一次.我知道我错过了或误解了什么.但是从这个帖子的第二个答案为什么我们需要使用flatMap?我认为第二个flatMap应该返回已处理的apiData,而是返回该Array上的每个对象项.我很感激你的帮助.
谢谢.
链接一系列HttpClient调用的“最佳实践”是什么(假设当前调用取决于先前调用的结果)?以下解决方案是有效的,但显然不建议这样做。每个get返回一个Observable。在解决方案(RxJs中的较新方法)中首选使用“管道”运算符。
ngOnInit() {
this.firstService.get().subscribe((first) => {
this.secondService.get().subscribe(second => {
this.thirdService.get().subscribe(third => {
... possibly more nested calls ...
})
})
})
}
Run Code Online (Sandbox Code Playgroud) rxjs ×11
angular ×5
javascript ×5
observable ×4
rxjs5 ×2
asynchronous ×1
callback ×1
chaining ×1
frp ×1
promise ×1
ramda.js ×1
subscribe ×1
typescript ×1
wait ×1