Javascript 使用较大文件阻止文件上载 简介

Javascript 使用较大文件阻止文件上载 简介,javascript,reactjs,redux,react-redux,redux-saga,Javascript,Reactjs,Redux,React Redux,Redux Saga,我试图实现的是一个简单的文件上传,带有redux saga和react的进度指示。我在得到这个指示时遇到了问题,因为文件上传似乎被阻塞了——这是不应该的 预期行为 在文件上载开始之前,会触发重新渲染,并显示微调器,并且不会阻止窗口 当前行为 我现在拥有的是一个组件,它有一个表,每行显示一个文件。当用户上载文件时,将添加一个带有微调器的乐观行作为内容。一旦上传文件,乐观的行将替换为带有文件名称等的真实行。当我上传大约50MB的文件时,窗口会被阻止,在上传文件之前不久(大约0.5s之前),微调器出现

我试图实现的是一个简单的文件上传,带有redux saga和react的进度指示。我在得到这个指示时遇到了问题,因为文件上传似乎被阻塞了——这是不应该的

预期行为 在文件上载开始之前,会触发重新渲染,并显示微调器,并且不会阻止窗口

当前行为 我现在拥有的是一个组件,它有一个表,每行显示一个文件。当用户上载文件时,将添加一个带有微调器的乐观行作为内容。一旦上传文件,乐观的行将替换为带有文件名称等的真实行。当我上传大约50MB的文件时,窗口会被阻止,在上传文件之前不久(大约0.5s之前),微调器出现,然后文件已经上传,微调器再次消失


旁注
  • 如果用
    newpromise(res=>setTimeout(res,5000))
    替换文件上传,一切正常=>xhr/fetch似乎有问题
  • 我已经使用XHR、Promissions和onProgress回调实现了相同的功能,以确保问题不被发现。 实施看起来非常接近: 同样,在这个实现中,我也遇到了同样的问题——直到上传几乎结束时才停止
  • 如果我将log语句放入组件的render函数中,以查看是否在上载文件之前重新渲染,我会看到(一旦块停止并上载文件),render函数中的log语句实际上在完成文件上载之前正确触发,并带有时间戳
  • 在这个实现中,我使用的是相同的缩减器:乐观事件以及还原乐观事件的真实事件,它们通过相同的缩减器(这里称为fileReducer)
  • 使用第二个减速机和浓缩而不是乐观还原逻辑有助于更早地显示微调器,但无助于阻塞。因此,中间件似乎也被阻塞调用阻塞。

saga:(postData使用fetch)
问题是,我确实以base64编码字符串的形式发送了文件,并使用错误的内容类型设置了请求

'Content-Type':'text/plain;字符集=UTF-8'


将文件放入FormData对象并发送不包含所述内容类型的请求将导致非阻塞请求。

预期行为发生在较小的文件中?@SH yes,但当然,它不那么引人注目,因为文件上载速度快得多。什么是actions.denormalizeEvent&actions.sendCommandSuccess?@SH它是CQS环境-sendCommandSuccess操作将向域发送命令-从域返回的事件将导致denormalizeEvent操作。因此,denormalizeEvent操作是为修改redux状态而触发的操作-它的有效负载确定哪个reducer处理该操作(有一个包装器)。-我会在问题中添加注释-谢谢。很难说清楚,但似乎
操作。非规范化事件
取决于以后的事件?(actions.sendCommandSuccess?)
function* createDocument(partnerId, { payload, meta }) {
  const siteId = getSiteIdFromRoute();
  const {
    mediaGroupId,
    customArticleId,
    logicalComponentId,
    type,
    name,
    documentSrc,
    meta: metaFromFrontEnd
  } = payload;

  const commonEventId = uuid();
  const hans = {
    optimistic: true
  };
  const payloadBasic = {
    id: commonEventId,
    version: 0,
    aggregate: {
      id: uuid(),
      name: 'document'
    },
    context: {
      name: 'contentManagement'
    },
    payload: {
      name,
      type,
      links: {
        partnerId,
        siteId,
        logicalComponentId,
        customArticleId,
        mediaGroupId
      }
    }
  };

  // creates the optimistic (fake) row with a spinner in the file list component - action marked as optimistic which will be reverted.
  yield put(actions.denormalizeEvent({
    ...payloadBasic,
    name: 'documentCreated',
    optimistic: true,
    payload: {
      ...payloadBasic.payload,
      uploading: true
    }
  }));
  yield fork(executeDocumentUpload, type, siteId, partnerId, documentSrc, payloadBasic);
}

function* executeDocumentUpload(type, siteId, partnerId, documentSrc, payloadBasic) {
  const req = yield call(uploadDocument, type, siteId, partnerId, documentSrc);
  const body = yield req.json();
  const { meta: metaFromFileUpload, id } = body.response;
  // removes the optimistic (fake) row from the file list component and and adds the real row with more file information (optimistic event gets reverted in middleware)
  yield put(actions.sendCommandSuccess({
    ...payloadBasic,
    name: 'createDocument',
    payload: {
      ...payloadBasic.payload,
      meta: metaFromFileUpload
    }
  }));
}

function uploadDocument(type, siteId, partnerId, documentSrc) {
  let url;
  if (type === 'site' || type === 'mediaGroup' || type ===     'logicalComponent') {
    url = `/file/site/${siteId}/document`;
  } else if (type === 'customArticle') {
    url = `/file/partner/${partnerId}/document`;
  }
  return postData(url, documentSrc);
}