React Redux with SAGA - 创建相同动作的队列
React Redux with SAGA - Create a queue of the same action
我有一个应用程序,每次检索 axios
50 个项目的数据并对它们进行分页。最初我打了两个电话,第一次准备当前页面(25 项),第二次准备下一页(25 项)。
然后每次用户点击下一页时,它都会调用其他 50 个项目,依此类推。
因此该应用会“在幕后”检索数据并准备下一页以获得更好的用户体验。
我的问题是,我如何使用 SAGA
创建呼叫队列?
如果用户多次点击下一页,我的调用“拥塞”可能(已经测试)第 3 次在第 4 次之后结束,那么数据不按顺序。
我想要的是:
1 call => end =>
2 call => end =>
3 call => end =>
4 call => end =>
等等...
我用的函数是setSpotifyData()
那是我的代码:
// first call just for the token and when the token expires
function* getSpotifyData(obj) {
try {
yield put({
type: "GET_SPOTIFY_USER_DATA_SUCCESS",
payload: obj.payload,
});
} catch (error) {
yield put({ type: "GET_SPOTIFY_USER_DATA_ERROR", payload: error });
}
}
// 我想“排队”的函数:
function* setSpotifyData(obj) {
const url = "http://localhost:8888/api/spotifyuserdata";
// route the needs auth
const config = {
method: "GET",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${obj.payload.token}`,
},
// becomes query in the route
params: obj.payload,
url: url,
transformResponse: [
(data) => {
return data;
},
],
};
try {
const spotifyData = yield axios(config);
/**
* @description Remapping to make it lighter
*/
...code...
yield put({
type: "SET_SPOTIFY_USER_DATA_SUCCESS",
payload: newAlbumsArr,
});
return newAlbumsArr;
} catch (error) {
yield put({ type: "SET_SPOTIFY_USER_DATA_ERROR", payload: error });
} finally {
yield put({ type: "SET_SPOTIFY_USER_DATA_END" });
}
}
function* watchAllSpotifyUserDataSaga() {
yield takeEvery("GET_SPOTIFY_USER_DATA", getSpotifyData);
yield takeEvery("SET_SPOTIFY_USER_DATA", setSpotifyData);
}
export default watchAllSpotifyUserDataSaga;
我已经尝试使用 SAGA 的 throttle
。但实际上并没有改变。
我也想在加载时禁用按钮,但我想尝试一下并学习一些新东西。
提前致谢
您正在使用 takeEvery 帮助程序,它执行所有 GET_SPOTIFY_USER_DATA 操作并调用 getSpotifyData 但问题是它允许 同时调用多个 getSpotifyData 实例 。换句话说,您可能会在上一个任务尚未终止时开始新任务,这就是为什么您的数据顺序可能不正确的原因。
您可以使用 actionChannel 效果,根据文档,它会生成一个动作队列并一个一个地执行它们。这意味着我们在处理完上一个动作后执行下一个动作。
为此,您需要在 getSpotifyData 函数中创建一个频道
function* getSpotifyData(obj) {
const usersChannel = yield actionChannel('GET_SPOTIFY_USER_DATA')
while (true) {
try {
const {payload} = yield take(usersChannel)
yield call(setSpotifyData, payload)
} catch (error) {
console.error('some error:', error)
}
}
您通过 put 发送到存储的来自 getSpotiFyData 的操作需要移动到您的 worker saga,即 setSpotiFyData,如果您需要的话。
你的 saga watchAllSpotifyUserDataSaga 现在也需要修改。
您可以改写如下:
export default function* watchAllSpotifyUserDataSaga() {
yield all([
getSpotiFyData(),
//some other sagas but I don't think you need to include setSpotifyData here
//as it's called from the other saga
])
}
我有一个应用程序,每次检索 axios
50 个项目的数据并对它们进行分页。最初我打了两个电话,第一次准备当前页面(25 项),第二次准备下一页(25 项)。
然后每次用户点击下一页时,它都会调用其他 50 个项目,依此类推。
因此该应用会“在幕后”检索数据并准备下一页以获得更好的用户体验。
我的问题是,我如何使用 SAGA
创建呼叫队列?
如果用户多次点击下一页,我的调用“拥塞”可能(已经测试)第 3 次在第 4 次之后结束,那么数据不按顺序。
我想要的是:
1 call => end =>
2 call => end =>
3 call => end =>
4 call => end =>
等等...
我用的函数是setSpotifyData()
那是我的代码:
// first call just for the token and when the token expires
function* getSpotifyData(obj) {
try {
yield put({
type: "GET_SPOTIFY_USER_DATA_SUCCESS",
payload: obj.payload,
});
} catch (error) {
yield put({ type: "GET_SPOTIFY_USER_DATA_ERROR", payload: error });
}
}
// 我想“排队”的函数:
function* setSpotifyData(obj) {
const url = "http://localhost:8888/api/spotifyuserdata";
// route the needs auth
const config = {
method: "GET",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${obj.payload.token}`,
},
// becomes query in the route
params: obj.payload,
url: url,
transformResponse: [
(data) => {
return data;
},
],
};
try {
const spotifyData = yield axios(config);
/**
* @description Remapping to make it lighter
*/
...code...
yield put({
type: "SET_SPOTIFY_USER_DATA_SUCCESS",
payload: newAlbumsArr,
});
return newAlbumsArr;
} catch (error) {
yield put({ type: "SET_SPOTIFY_USER_DATA_ERROR", payload: error });
} finally {
yield put({ type: "SET_SPOTIFY_USER_DATA_END" });
}
}
function* watchAllSpotifyUserDataSaga() {
yield takeEvery("GET_SPOTIFY_USER_DATA", getSpotifyData);
yield takeEvery("SET_SPOTIFY_USER_DATA", setSpotifyData);
}
export default watchAllSpotifyUserDataSaga;
我已经尝试使用 SAGA 的 throttle
。但实际上并没有改变。
我也想在加载时禁用按钮,但我想尝试一下并学习一些新东西。
提前致谢
您正在使用 takeEvery 帮助程序,它执行所有 GET_SPOTIFY_USER_DATA 操作并调用 getSpotifyData 但问题是它允许 同时调用多个 getSpotifyData 实例 。换句话说,您可能会在上一个任务尚未终止时开始新任务,这就是为什么您的数据顺序可能不正确的原因。
您可以使用 actionChannel 效果,根据文档,它会生成一个动作队列并一个一个地执行它们。这意味着我们在处理完上一个动作后执行下一个动作。
为此,您需要在 getSpotifyData 函数中创建一个频道
function* getSpotifyData(obj) {
const usersChannel = yield actionChannel('GET_SPOTIFY_USER_DATA')
while (true) {
try {
const {payload} = yield take(usersChannel)
yield call(setSpotifyData, payload)
} catch (error) {
console.error('some error:', error)
}
}
您通过 put 发送到存储的来自 getSpotiFyData 的操作需要移动到您的 worker saga,即 setSpotiFyData,如果您需要的话。
你的 saga watchAllSpotifyUserDataSaga 现在也需要修改。
您可以改写如下:
export default function* watchAllSpotifyUserDataSaga() {
yield all([
getSpotiFyData(),
//some other sagas but I don't think you need to include setSpotifyData here
//as it's called from the other saga
])
}