Redux-saga上传文件进度事件

时间:2016-11-18 20:15:57

标签: reactjs redux redux-saga

我正在使用redux-saga来上传文件,我试图找到一种方法来在上传进度发生变化时发送事件:

const data = new FormData();

data.append('file', fileWrapper.file);

const uploadedFile = yield call(request, requestURL, {
  method: 'POST',
  headers: {
     'X-Requested-With': 'XMLHttpRequest'
  },
  body: data
});

知道如何附加上传进度事件吗?

1 个答案:

答案 0 :(得分:7)

首先,答案取决于你如何进行uploadRequest。

好像您正在使用window.fetch API。此API不提供接收上传进度事件的方法。

因此,您需要切换到使用XMLHttpRequest或以方便的方式包装它的库。我建议您查看axiossuperagent。它们都提供了一种倾听进展事件的方法。

下一个主题是如何在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

P.S。在我个人看来,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});
           }
      });
  }
}