Redux 传奇、axios 和进度事件 [英] Redux saga, axios and progress event

查看:26
本文介绍了Redux 传奇、axios 和进度事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否有干净/简短/正确的方法来一起使用 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆