【发布时间】:2017-06-15 16:21:15
【问题描述】:
我制作了一个包装器,用于使用身份验证标头访问“rxjs/observable/dom/ajax”函数。那部分没问题。
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 请求。我最近回答了一个类似的问题:stackoverflow.com/questions/44496395/…
-
zip 对我不起作用,因为我必须在返回之前完成从 authjax 返回的任何内容,因此我无法将以下链式方法添加到 zip 中。我在返回的 observable 上尝试了 .ignoreElements() ,但它也忽略了我返回的第一个元素,它只拾取链中与错误相关的事件。如果我抛出一个错误然后链接到 .ignoreElements,我的 catch 语句稍后会触发。我可能试图让 rxjs 做一些不应该做的事情。
标签: javascript error-handling rxjs reactive-programming redux-observable