Redux 传奇、axios 和进度事件 [英] Redux saga, axios and progress event
问题描述
是否有干净/简短/正确的方法来一起使用 axios 承诺和上传进度事件?
Is there clean/short/right way to using together axios promise and uploading progress event?
假设我有下一个上传功能:
Suppose I have next upload function:
function upload(payload, onProgress) {
const url = '/sources/upload';
const data = new FormData();
data.append('source', payload.file, payload.file.name);
const config = {
onUploadProgress: onProgress,
withCredentials: true
};
return axios.post(url, data, config);
}
这个函数返回了承诺.
我还有一个传奇:
function* uploadSaga(action) {
try {
const response = yield call(upload, payload, [?? anyProgressFunction ??]);
yield put({ type: UPLOADING_SUCCESS, payload: response });
} catch (err) {
yield put({ type: UPLOADING_FAIL, payload: err });
}
}
我想接收进度事件并将其放在 saga 中.我还想捕获 axios 请求的成功(或失败)结果.可能吗?
I want to receive progress events and put it by saga. Also I want to catch success (or failed) result of the axios request. Is it possible?
谢谢.
推荐答案
所以我找到了答案,感谢 Mateusz Burzyński 澄清.
So I found the answer, thanks Mateusz Burzyński for the clarification.
我们需要使用 eventChannel,但有点难.
We need use eventChannel, but a bit canningly.
假设我们有上传文件的api函数:
Suppose we have api function for uploading file:
function upload(payload, onProgress) {
const url = '/sources/upload';
const data = new FormData();
data.append('source', payload.file, payload.file.name);
const config = {
onUploadProgress: onProgress,
withCredentials: true
};
return axios.post(url, data, config);
}
在 saga 中,我们需要创建 eventChannel,但将其放在外面.
In saga we need to create eventChannel but put emit outside.
function createUploader(payload) {
let emit;
const chan = eventEmitter(emitter => {
emit = emitter;
return () => {}; // it's necessarily. event channel should
// return unsubscribe function. In our case
// it's empty function
});
const uploadPromise = upload(payload, (event) => {
if (event.loaded.total === 1) {
emit(END);
}
emit(event.loaded.total);
});
return [ uploadPromise, chan ];
}
function* watchOnProgress(chan) {
while (true) {
const data = yield take(chan);
yield put({ type: 'PROGRESS', payload: data });
}
}
function* uploadSource(action) {
const [ uploadPromise, chan ] = createUploader(action.payload);
yield fork(watchOnProgress, chan);
try {
const result = yield call(() => uploadPromise);
put({ type: 'SUCCESS', payload: result });
} catch (err) {
put({ type: 'ERROR', payload: err });
}
}
这篇关于Redux 传奇、axios 和进度事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!