我需要进行5个可以并行执行的http调用+另外需要在这五个调用之后执行的http调用。
我使用forkJoin作为前5个,但我不知道如何链接flatMap(或其他函数)。
forkJoin(
firstObservable,
secondObservable,
thirdObservable,
..)
.subscribe(results => {
this.myComposedObject = results[0];
let secondResult = results[1];
let thirdResult = results[2];
[...]
// !!! AT THIS POINT I WOULD NEED TO MAKE AN EXTRA CALL!
// results[1] contains data I need to make the extra call
//
this.myComposedObject.second = secondResult;
this.myComposedObject.third = thirdResult;
});
我在组件中执行此操作,因此最后我将数据分配给myComposedObject。
答案 0 :(得分:3)
就像你说要发出5个并行请求一样,你可以使用forkJoin
。然后,您希望在前5个完成后再发出请求,以便将其与concatMap
运算符链接起来(或mergeMap
也适用于此处)。
然后您需要处理所有结果,这样您就可以使用map
将最后一个结果添加到与前五个相同的数组中。
forkJoin(
firstObservable,
secondObservable,
thirdObservable,
...
)
.concatMap(firstFiveResults => makeAnotherCall(firstFiveResults[1])
.map(anotherResult => [...firstFiveResults, anotherResult])
)
.subscribe(allResults => {
this.myComposedObject.second = allResults[1];
this.myComposedObject.third = allResults[2];
// allResults[5] - response from `makeAnotherCall`
....
});
答案 1 :(得分:0)
谢谢,这指向了正确的方向。 我在结果类型方面遇到了一些问题。当我试图分配
时weak
编译器抱怨类型转换,所以我会在这里为其他人报告我的解决方案。
为了摆脱这个问题,你可以利用“解构”(这里有更多信息:https://developer.mozilla.org/it/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment)
@IBOutlet weak fileprivate var yourLabel: UILabel!
var timeMin = 0
var timeSec = 0
weak var timer: Timer?
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// if your presenting this vc yourLabel.txt will show 00:00
yourLabel.txt = String(format: "%02d:%02d", timeMin, timeSec)
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
resetTimerToZero()
}
// MARK:- recordButton
@IBAction fileprivate func recordButtonTapped(_ sender: UIButton) {
startTimer()
movieFileOutput.startRecording(to: videoUrl, recordingDelegate: self)
}
// MARK:- Timer Functions
fileprivate func startTimer(){
// if you want the timer to reset to 0 every time the user presses record you can uncomment out either of these 2 lines
// timeSec = 0
// timeMin = 0
// If you don't use the 2 lines above then the timer will continue from whatever time it was stopped at
let timeNow = String(format: "%02d:%02d", timeMin, timeSec)
yourLabel.txt = timeNow
stopTimer() // stop it at it's current time before starting it again
timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { [weak self] _ in
self?.timerTick()
}
}
@objc fileprivate func timerTick(){
timeSec += 1
if timeSec == 60{
timeSec = 0
timeMin += 1
}
let timeNow = String(format: "%02d:%02d", timeMin, timeSec)
yourLabel.txt = timeNow
}
// resets both vars back to 0 and when the timer starts again it will start at 0
@objc fileprivate func resetTimerToZero(){
timeSec = 0
timeMin = 0
stopTimer()
}
// if you need to reset the timer to 0 and yourLabel.txt back to 00:00
@objc fileprivate resetTimerAndLabel(){
resetTimerToZero()
yourLabel.txt = String(format: "%02d:%02d", timeMin, timeSec)
}
// stops the timer at it's current time
@objc fileprivate stopTimer(){
timer?.invalidate()
}