在 Redux-saga 中,如何在一个 saga 的 fetch 中调用一个 saga?
In Redux-saga, how to call a saga in one saga's fetch?
在我的 React 应用程序中,有一个 Saga 调用后端 API 来检索一些图表数据。请阅读源代码
function fetchData () {
return fetch(`${config.base}dashboard_charts.json`)
.then((response) => {
if (response.status === 200) {
return response.json();
} else if (response.status === 403) {
return 'logon';
}
});
}
function * getData (action) {
try {
const charts = yield call(fetchData);
if (charts === 'logon') {
yield logon();
} else {
yield put({ type: UPDATE_DASHBOARD_CHART, charts });
}
} catch (error) {
yield put({ type: UPDATE_DASHBOARD_CHART, charts: [] });
}
}
function * logon (action) {
yield auth();
}
export default function * portfolio () {
yield [
takeEvery(FETCH_DASHBOARD_CHART, getData)
];
};
函数 fetchData 中有一个针对 http 响应状态的检查,如果状态为 200 则直接 return 响应。但是如果服务器端returns 403,说明客户端需要认证,程序会去auth()执行登录。
但是,http 响应状态代码检查在某种程度上是适用于所有 API 调用的通用功能。所以我不想在每个传奇中都重复这种代码。为此,我编写了一个服务 'responseHandler' 来对内部的响应代码检查进行分组,如下所示:
export default function responseHandler (resp) {
if (resp.status === 401 || resp.status === 403) {
yield auth();
} else if (resp.status === 200) {
} else {
console.log('error handling');
}
};
并且会在fetchData
中调用
return fetch(`${config.base}dashboard_charts.json`)
.then((response) => {
responseHandler(response);
});
但这种方法永远行不通。 'yield auth()' 在 responseHandler 中无效。
谁能建议如何更好地设计这种情况的代码?
也许组织多个逻辑有意义?
首先,可以修改fetch-wrapper,以便在响应代码的HTTP来源不符合形成成功结果的预期的情况下,执行到catch-section的转换。它将允许以纯 Promise 的形式保存 fetchData
函数,而无需将生成器逻辑输入其中。
其次,auth
和 logon
函数的本质不是特别清楚。如果通过此类操作的结果生成登录表单,则通过适当的 redux 操作实现它。如果需要转换到其他页面,请使用 react-redux-router
.
function fetchData () {
return fetch(`${config.base}dashboard_charts.json`).then(response => (
(response.status === 200) ? response.json() : Promise.reject('logon')
));
}
function* getData (action) {
try {
const charts = yield call(fetchData);
yield put({ type: UPDATE_DASHBOARD_CHART, charts });
} catch (error) {
yield put({ type: UPDATE_DASHBOARD_CHART, charts: [] });
if(error.message === 'logon') {
yield put({ type: PERMORM_AUTORIZE });
}
}
}
export default function * portfolio () {
yield [ takeEvery(FETCH_DASHBOARD_CHART, getData) ];
};
而且你的逻辑是不是更复杂,就用redux-saga
中的fork
。它允许执行更复杂的任务。
在我的 React 应用程序中,有一个 Saga 调用后端 API 来检索一些图表数据。请阅读源代码
function fetchData () {
return fetch(`${config.base}dashboard_charts.json`)
.then((response) => {
if (response.status === 200) {
return response.json();
} else if (response.status === 403) {
return 'logon';
}
});
}
function * getData (action) {
try {
const charts = yield call(fetchData);
if (charts === 'logon') {
yield logon();
} else {
yield put({ type: UPDATE_DASHBOARD_CHART, charts });
}
} catch (error) {
yield put({ type: UPDATE_DASHBOARD_CHART, charts: [] });
}
}
function * logon (action) {
yield auth();
}
export default function * portfolio () {
yield [
takeEvery(FETCH_DASHBOARD_CHART, getData)
];
};
函数 fetchData 中有一个针对 http 响应状态的检查,如果状态为 200 则直接 return 响应。但是如果服务器端returns 403,说明客户端需要认证,程序会去auth()执行登录。
但是,http 响应状态代码检查在某种程度上是适用于所有 API 调用的通用功能。所以我不想在每个传奇中都重复这种代码。为此,我编写了一个服务 'responseHandler' 来对内部的响应代码检查进行分组,如下所示:
export default function responseHandler (resp) {
if (resp.status === 401 || resp.status === 403) {
yield auth();
} else if (resp.status === 200) {
} else {
console.log('error handling');
}
};
并且会在fetchData
中调用return fetch(`${config.base}dashboard_charts.json`)
.then((response) => {
responseHandler(response);
});
但这种方法永远行不通。 'yield auth()' 在 responseHandler 中无效。
谁能建议如何更好地设计这种情况的代码?
也许组织多个逻辑有意义?
首先,可以修改fetch-wrapper,以便在响应代码的HTTP来源不符合形成成功结果的预期的情况下,执行到catch-section的转换。它将允许以纯 Promise 的形式保存 fetchData
函数,而无需将生成器逻辑输入其中。
其次,auth
和 logon
函数的本质不是特别清楚。如果通过此类操作的结果生成登录表单,则通过适当的 redux 操作实现它。如果需要转换到其他页面,请使用 react-redux-router
.
function fetchData () {
return fetch(`${config.base}dashboard_charts.json`).then(response => (
(response.status === 200) ? response.json() : Promise.reject('logon')
));
}
function* getData (action) {
try {
const charts = yield call(fetchData);
yield put({ type: UPDATE_DASHBOARD_CHART, charts });
} catch (error) {
yield put({ type: UPDATE_DASHBOARD_CHART, charts: [] });
if(error.message === 'logon') {
yield put({ type: PERMORM_AUTORIZE });
}
}
}
export default function * portfolio () {
yield [ takeEvery(FETCH_DASHBOARD_CHART, getData) ];
};
而且你的逻辑是不是更复杂,就用redux-saga
中的fork
。它允许执行更复杂的任务。