0
我做了一个包装,用于通过身份验证头访问'rxjs/observable/dom/ajax'函数。那部分还行。我该如何使用rxjs尽早逃脱一个catch链?
export const authjax = {
create: urlOrRequest => ajax(typeof urlOrRequest === 'string'
? {url: urlOrRequest, headers: authHeader()} : _.merge({}, urlOrRequest, {headers: authHeader()})
),
get: (url, headers = {}) => ajax.get(url, {...headers, ...authHeader()}),
post: (url, body = {}, headers = {}) => ajax.post(url, body, {...headers, ...authHeader()}),
put: (url, body = {}, headers = {}) => ajax.put(url, body, {...headers, ...authHeader()}),
patch: (url, body = {}, headers = {}) => ajax.patch(url, body, {...headers, ...authHeader()}),
getJSON: (url, headers = {}) => ajax.getJSON(url, {...headers, ...authHeader()})
};
所以,这是用来代替ajax。这是一个在史诗中使用的例子。
export const getBatchesEpic = (action$, store) =>
action$.ofType(actions.GET_BATCHES)
.switchMap(action => {
const {paginate, refresh} = action;
const paginatorNext = _.get(store.getState(), 'manager.paginator.batches.next');
const usePaginatorNext = paginatorNext && paginate && !refresh;
return authjax.get(usePaginatorNext ? paginatorNext : `${API_URL}/batches/`)
.concatMap(({response}) => {
const incompleteBatches = response.results.filter(batch => !batch.completed);
const checkBatchActions = incompleteBatches.map(batch => checkBatch(batch.id));
return [
{type: actions.BATCHES_RECEIVED, data: response, next: response.next, paginate},
...checkBatchActions
];
})
.catch(error => Observable.of({type: actions.GET_BATCHES_ERROR, error})
);
});
现在,我在试图使只使用authjax.get
方法简单的测试通过的第一阶段。我希望401服务器的响应被authjax抓住,authjax返回一个注销动作,以及取消任何下面的链接方法。
这是我的最新尝试authjax.get
。它适用于成功的Ajax响应,以及非401 ajax响应。它不返回任何东西,甚至注销动作,当它击中401
export const authjax = {
create: urlOrRequest => ajax(typeof urlOrRequest === 'string'
? {url: urlOrRequest, headers: authHeader()} : _.merge({}, urlOrRequest, {headers: authHeader()})
),
get: (url, headers = {}) => {
const call = ajax.get(url, {...headers, ...authHeader()});
return call.catch(error => {
if (_.get(error, 'status') === 401) {
console.log('401!!!', Observable.of({type: actions.LOGOUT}));
return Observable.of({type: actions.LOGOUT}).ignoreElements();
}
return call;
});
},
post: (url, body = {}, headers = {}) => ajax.post(url, body, {...headers, ...authHeader()}),
put: (url, body = {}, headers = {}) => ajax.put(url, body, {...headers, ...authHeader()}),
patch: (url, body = {}, headers = {}) => ajax.patch(url, body, {...headers, ...authHeader()}),
getJSON: (url, headers = {}) => ajax.getJSON(url, {...headers, ...authHeader()})
};
我读rxjs文档,但发现没有,你会不会需要转出或取消的假设流中的流。我知道有些选项可以在Epic本身中处理更多,但我希望authjax能够处理自己的身份验证问题,因此我可以将它用作使用相同身份验证的多个应用程序的导入。
我不得不做几次 - 根据concatMap里面的结果取消所有concatMap的等待请求。我最近回答了一个类似的问题:https://stackoverflow.com/questions/44496395/rxjs-chain-observables-completing-at-any-point/44505681#44505681 –
压缩不适合我,因为我必须完成任何从authjax返回之前返回它,所以我不能将以下链接的方法添加到zip。 我在返回的observable上尝试过.ignoreElements(),但它也忽略了我返回的第一个元素,它只拾取链中的错误相关事件。如果我抛出一个错误,然后链接.ignoreElements,我的catch语句将在链中触发。 我可能会试图让rxjs做一些它不应该做的事情。 – Sally