description from the book:
URLSession.rx.response(request:) sends your request to the server, and upon receiving the response, emits a .next event just once with the returned data, and then completes.
In this situation, if the observable completes and then you subscribe to it again, that will create a new subscription and will fire another identical request to the server.
To prevent situations like this, you use share(replay:scope:). This operator keeps a buffer of the last replay elements emitted and feeds them to any newly subscribed observers. Therefore, if your request has completed and a new observer subscribes to the shared sequence (via share(replay:scope:)), it will immediately receive the buffered response from the previously-executed network request.
I wrote some demo code to mimic the networking code, just as how URLSession.rx.response(request:)
is work.
let just = Observable.just("nothing here")
.flatMap { _ in
return Observable<Int>.create { observer in
print("start")
DispatchQueue.main.asyncAfter(deadline: .now() + 2, execute: {
observer.onNext(4)
observer.onCompleted()
})
return Disposables.create()
}
}
// .share()
.share(replay: 1)
//1
just.subscribe(onNext: {
print($0)
}, onCompleted: {
print("completed")
})
//2
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
just.subscribe(onNext: {
print($0)
}, onCompleted: {
print("completed")
})
}
//3
DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
just.subscribe(onNext: {
print($0)
}, onCompleted: {
print("completed")
})
}
the output:
start
4
4
completed
completed
start
4
completed
When the inner observable completes, the third subscription restart the whole process other than replay the last value.
Why? Is there any bugs in my code or the description in this book is wrong?