问题
I've got a web application where I'm using the Rx.js for handling event streams. The app uses a rest api provided by a backend.
Mostly I make a subscription for an api call and when a request is done I render results and reset other controls states (hide progress elements and so on).
Some api calls can be failed when an auth token is expired and I have to make a user to login again (show a login popup or so).
I'm curious is there a way to "restore" an api call stream after a successful login? Where a user has not to provide additional actions to get a server response.
Primitive example of the current workflow:
var apiCallStream = $.ajaxAsObservable(params):
apiCallStream.subscribe(
result => renderResult(result),
err => handleError(err));
function handleError(err) {
if (err.xhr.error === 401) {
LoginPopup();
} else {
ErrorPopup(err);
}
}
回答1:
Here some some (very rough pseudo-code), but you could do this with retryWhen:
// use Rx.DOM.get for an Observable Ajax GET
var source = Rx.DOM.get('/some/end/point')
.retryWhen(function(errors) {
// retryWhen: errors is a stream of errors
// whatever observable you return, when it emits, the
// observable you're operating on will be retried. (the entire thing)
return errors.filter(function(e) { return e.status === 401; })
// if status is 401, then tell the user to login
.flatMapLatest(function() { return doUserLogin; });
});
// a contrived observable that shows a form and
// return a stream of successful logins
var doUserLogin = Observable.create(function(observer) {
// show a form
var form = $('.my-form').show();
// when submit is fired on said form...
return Rx.Observable.fromEvent(form, 'submit')
// send a login over ajax
.flatMap(e => Rx.DOM.post('some/url/login', form.serialize()))
});
Hopefully that gives you something to start with.
来源:https://stackoverflow.com/questions/31392730/rx-js-and-application-workflow