首先,答案取决于你如何做uploadRequest。
看起来好像你在使用window.fetch API。此API不会为您提供接收上传进度事件的方法。
所以,你需要切换到使用XMLHttpRequest
或一个库,它以一种方便的方式为你包装它。我建议你看看axios和superagent。他们都提供了一种倾听进度事件的方式。
下一个主题是如何调度redux-saga
中的进度操作。您需要使用fork
创建分叉的异步任务并在那里分派操作。
function uploadEmitter(action) {
return eventChannel(emit => {
superagent
.post('/api/file')
.send(action.data)
.on('progress', function(e) {
emit(e);
});
});
}
function* progressListener(chan) {
while (true) {
const data = yield take(chan)
yield put({ type: 'PROGRESS', payload: data })
}
}
function* uploadSaga(action) {
const emitter = uploadEmitter()
yield fork(progressListener, emitter)
const result = yield call(identity(promise))
yield put({ type: 'SUCCESS', payload: result })
}
来源:https://github.com/redux-saga/redux-saga/issues/613#issuecomment-258384017
附:我个人认为,redux-saga并不是实现这种功能的适当工具。与redux-thunk
做这个会更干净:
function uploadAction(file) {
return dispatch => {
superagent
.post('/api/file')
.send(action.data)
.on('progress', function(event) {
dispatch({type: 'UPLOAD_PROGRESS', event});
})
.end(function(res) {
if(res.ok) {
dispatch({type: 'UPLOAD_SUCCESS', res});
} else {
dispatch({type: 'UPLOAD_FAILURE', res});
}
});
}
}
很好的解决方案。你能否详细说明'identity'和'promise'来自'yield call(identity(promise))'行吗?谢谢! –
我上个星期就在想,创建一个使用redux和redux-saga的上传器是个好主意。所以我决定为它创建一个库 - https://github.com/el-davo/react-typescript-upload-saga –
Nik所以,检查代码在https://github.com/redux-saga/redux-佐贺/问题/ 613#issuecomment-258384017 –