首先,答案取決於你如何做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 –