用axios onProgress可以观察到redux

时间:2018-03-05 21:52:49

标签: axios redux-observable

我正在创建一个上传功能,该功能会在React ReduxRedux-observable内向客户端显示进度条,并使用axios执行放置请求到AWS S3。

我的史诗如下

...

function uploadFile(mimetype, url, file) {
  const config = {
    headers: {
      'Content-Type': mimetype,
    },
    onUploadProgress(progress) {
      const percentCompleted = Math.round((progress.loaded * 100) / progress.total)
      uploadProgress(percentCompleted)
    },
  }

  axiosRetry(axios, { retries: 3 })

  return axios.put(url, file[0], config)
}

export const uploadEpic = (action$, store) => action$
  .ofType(SIGNED_URL_SUCCESS)
  .mergeMap(() => {
    const file = store.getState().File.droppedFile
    const mimetype = file[0].type
    const { url } = store.getState().SignedUrl
    const { fileData } = store.getState().Upload

    return of(uploadFile(mimetype, url.data, file))
      .concatMap(() => {
        const uploadedData = {
          url: fileData.url,
          thumbUrl: `${fileData.folder}/${fileData.filename}-00001.png`,
        }
        return [
          upload(uploadedData),
          uploadSuccess(),
        ]
      })
      .catch(error => of(uploadFailure(error)))
  })

export default uploadEpic

上传似乎有效,因为我收到了一封AWS SNS电子邮件,告诉它已完成,但我似乎无法看到它正在更新我的上传减速器中的Upload.progress状态。

我使用axios的原因是特别的,因为它axios-retry及其onUploadProgress,因为我似乎无法找到使用universal-rx-request

所以可能有两个问题

  1. 我如何使用axios
  2. 实现这一目标
  3. 如何使用universal-rx-request
  4. 实现此目的

1 个答案:

答案 0 :(得分:1)

感谢SO answer

我最终没有使用axios

我使用了这个

import { of } from 'rxjs/observable/of'
import { Subject } from 'rxjs/Subject'

import { Observable } from 'rxjs/Observable'
import 'rxjs/add/observable/dom/ajax'

import { SIGNED_URL_SUCCESS } from 'ducks/SignedUrl'

import {
  upload,
  uploadIsLoading,
  uploadSuccess,
  uploadFailure,
  uploadProgress,
} from 'ducks/Upload'

export const uploadEpic = (action$, store) => action$
  .ofType(SIGNED_URL_SUCCESS)
  .mergeMap(() => {
    const file = store.getState().File.droppedFile
    const mimetype = file[0].type
    const { url } = store.getState().SignedUrl
    const { fileData } = store.getState().Upload

    const progressSubscriber = new Subject()
    const request = Observable.ajax({
      method: 'PUT',
      url: url.data,
      body: file[0],
      headers: {
        'Content-Type': mimetype,
      },
      progressSubscriber,
    })

    const requestObservable = request
      .concatMap(() => {
        const uploadedData = {
            ...
        }
        return [
          upload(uploadedData),
          uploadIsLoading(false),
          uploadSuccess(),
        ]
      })
      .catch(error => of(uploadFailure(error)))

    return progressSubscriber
      .map(e => ({ percentage: (e.loaded / e.total) * 100 }))
      .map(data => uploadProgress(data.percentage))
      .merge(requestObservable)
  })