欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JavaScript獲取上傳進(jìn)度的幾種方式實(shí)現(xiàn)

 更新時(shí)間:2023年08月10日 09:06:48   作者:三原  
進(jìn)度條的應(yīng)用是為了顯示的告訴用戶文件上傳了多少,本文主要介紹了JavaScript獲取上傳進(jìn)度的幾種方式,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

獲取上傳進(jìn)度的幾種方式

今天測試說咱們的上傳后的等待界面都沒有l(wèi)oading, 看起來不像是等待界面需要優(yōu)化。然后產(chǎn)品說參考下其他業(yè)務(wù)的上傳搞下吧。 我以為就一個(gè)loading的事,發(fā)現(xiàn)其他業(yè)務(wù)上傳使用的是環(huán)形、線形進(jìn)度條。我說現(xiàn)在接口是沒有返回當(dāng)前進(jìn)度的,如果是以上傳完成后的文件數(shù)量(因?yàn)槲覀兪且粋€(gè)個(gè)文件上傳分批次調(diào)的接口)做判斷也不太準(zhǔn)確,因?yàn)槲募写笥行〉摹?/p>

后面就找另外一個(gè)前端同事聊了下他告訴我說axios是有監(jiān)聽整個(gè)上傳進(jìn)度api的,那我就針對文件上傳去了解了下做以下總結(jié):

前端使用axios實(shí)現(xiàn)監(jiān)聽上傳進(jìn)度

咱們先使用axios實(shí)現(xiàn)監(jiān)聽上傳進(jìn)度如下:

axios.post('/api/file/uploadfile', form, {
  headers: {
    'Content-Type': 'multipart/form-data',
  },
  onUploadProgress: (progressEvent) => {
    if (progressEvent.lengthComputable) {
      this.progresss = Math.round((progressEvent.loaded / progressEvent.total) * 100);
    }
  },
})
  .then((res) => {
   // ...
  });

前端使用ajax獲取上傳進(jìn)度

前端使用ajax如何獲取上傳進(jìn)度呢? 如下:

const xhr = new XMLHttpRequest();
xhr.upload.addEventListener('progress', (event) => {
  if (event.lengthComputable) {
    const progressPercentage = Math.round((event.loaded / event.total) * 100);
    console.log(`上傳進(jìn)度: ${progressPercentage}%`);
  }
});

前端使用fetch API獲取上傳進(jìn)度

如何使用fetch API獲取上傳的進(jìn)度呢?如下:

const file = document.getElementById('fileInput').files[0];
fetch('/upload', {
? method: 'POST',
? body: file,
? onprogress: (event) => {
? ? if (event.lengthComputable) {
? ? ? const progressPercentage = Math.round((event.loaded / event.total) * 100);
? ? ? console.log(`上傳進(jìn)度: ${progressPercentage}%`);
? ? }
? },
})
? .then((response) => {
? ? // 處理響應(yīng)結(jié)果
? })
? .catch((error) => {
? ? // 處理錯(cuò)誤
? });

上面幾種都是獲取上傳進(jìn)度展示的進(jìn)度條。那么咱們還有那些展示進(jìn)度條的方式呢?

多文件上傳展示一個(gè)進(jìn)度條

如果支持多個(gè)文件上傳,并已文件上傳個(gè)數(shù)展示進(jìn)度條的話,一般都是怎么做的呢?

需要考慮多個(gè)文件比如10個(gè)文件,在你上傳完第一個(gè)的時(shí)候進(jìn)度條需要控制再10%以下,依此類推。如下面一塊代碼:

let progress = 0;
const UPLOAD_TYPE_MAP = {
? UPLOADING: 'uploading',
? COMPLATE: 'complate',
}
const files = [{ file:'', status: UPLOAD_TYPE_MAP.UPLOADING }, { file:'', status: UPLOAD_TYPE_MAP.UPLOADING }];
for (let index = 0; index < files.length; index++) {
? const element = files[index];
? // 1、這里是調(diào)接口的邏輯,可以是并行也可以完成一個(gè)調(diào)下一個(gè),這個(gè)看你們的接口的限速吧,我就按照并行做了。
? // 2、這里是每個(gè)文件上傳完成的邏輯,更改當(dāng)前文件的狀態(tài)把status 改成UPLOAD_TYPE_MAP.COMPLATE
}
const timer = setInterval(() => {
? const eachProgress = 100 / files.length; // 計(jì)算單個(gè)的比例
? const complateUpload = files.filter((item) => item.status === UPLOAD_TYPE_MAP.COMPLATE);
? const upperLimit = (complateUpload.length + 1) * eachProgress;
? const maxProgress = upperLimit > 100 ? 100 : upperLimit; // 計(jì)算出當(dāng)前最大進(jìn)度
? if(progress < maxProgress) {
? ? progress++; // 邊界控制
? }
? if(maxProgress === 100) {
? ? progress = 100;
? ? clearInterval(time);
? }
}, 500);

上面就多文件展示一個(gè)進(jìn)度條的具體代碼。其實(shí)不是很準(zhǔn)確,文件有大有小,如果文件大小差不太多展示開可以。其實(shí)最好的方案是分別利用axios、ajax等分別展示一個(gè)進(jìn)度條。還是看業(yè)務(wù)需求吧,

大文件分片上傳展示進(jìn)度條

先簡單說下分片上傳的好處如下:

  • 可靠性和魯棒性:將大文件分成小塊進(jìn)行上傳,即使出現(xiàn)網(wǎng)絡(luò)中斷或其他意外情況,只需要重新上傳失敗的分片,而不需要重新上傳整個(gè)文件,提高上傳的可靠性和魯棒性。
  • 傳輸效率:由于大文件被分成多個(gè)小塊進(jìn)行并行上傳,可以充分利用網(wǎng)絡(luò)帶寬,提高傳輸速度和效率。
  • 斷點(diǎn)續(xù)傳:如果上傳過程中斷,可以根據(jù)已成功上傳的分片信息,從上次中斷的地方繼續(xù)上傳,避免重復(fù)上傳已經(jīng)上傳過的部分,節(jié)省時(shí)間和資源。
  • 內(nèi)存占用低:大文件一次性加載到內(nèi)存中可能導(dǎo)致內(nèi)存溢出,而分片上傳只需加載單個(gè)分片,減少了對內(nèi)存的壓力,并適應(yīng)內(nèi)存有限的環(huán)境。
  • 服務(wù)器負(fù)載平衡:使用分片上傳可以將上傳請求分散到多個(gè)服務(wù)器,降低單一服務(wù)器的負(fù)載壓力,提高整體系統(tǒng)的穩(wěn)定性和吞吐量。
  • 靈活性:分片上傳允許用戶在任意時(shí)間暫停、取消或恢復(fù)上傳過程,提供了更好的用戶體驗(yàn)和操作靈活性。

其實(shí)像咱們經(jīng)常說別的網(wǎng)站為啥有的上傳速度這么快,我用的網(wǎng)速一樣我的為啥這么慢。其實(shí)還有就是看你們上傳的文件大小有沒有必要做分片上傳,畢竟沒有直接一個(gè)接口上傳開發(fā)快,前端、服務(wù)端都需要增加工作成本。那咱們下面先看下怎么實(shí)現(xiàn)分片如下:

// 定義分片大?。ㄒ宰止?jié)為單位) // 1MB
// 將文件切割為多個(gè)分片
function sliceFileIntoChunks(file, chunkSize = 1024 * 1024) {
? const fileSize = file.size;
? const chunks = Math.ceil(fileSize / chunkSize);
? const fileChunks = [];
? let start = 0;
? let end = chunkSize;
? for (let i = 0; i < chunks; i++) {
? ? const chunk = file.slice(start, end); // slice 可以把文件按照需要的大小分割
? ? fileChunks.push(chunk);
? ? start = end;
? ? end = start + chunkSize;
? }
? return fileChunks;
}

獲取上傳進(jìn)度(這個(gè)需求又回到了【多文件上傳展示一個(gè)進(jìn)度條】上面)如下:

const files = sliceFileIntoChunks(originFile).map((item) => ({file: item, status: UPLOAD_TYPE_MAP.UPLOADING}));
// ... 忽略
const timer = setInterval(() => {
? const eachProgress = 100 / files.length; // 計(jì)算單個(gè)的比例
? const complateUpload = files.filter((item) => item.status === UPLOAD_TYPE_MAP.COMPLATE);
? const upperLimit = (complateUpload.length + 1) * eachProgress;
? const maxProgress = upperLimit > 100 ? 100 : upperLimit; // 計(jì)算出當(dāng)前最大進(jìn)度
? if(progress < maxProgress) {
? ? progress++; // 邊界控制
? }
? if(maxProgress === 100) {
? ? progress = 100;
? ? clearInterval(time);
? }
}, 500);

有一個(gè)點(diǎn)需要注意你要告訴服務(wù)端你得切片索引,后面服務(wù)端還要合并切片呢!??!。還有如果你們是按照大小切割的比如1M,你還要再上傳完成給服務(wù)端發(fā)送一個(gè)合并切片的通知。 如果你們是以份額切分的每次就分為10等份,那么這個(gè)上傳完成的請求你不再通知服務(wù)端也能判斷上。

結(jié)語

到此這篇關(guān)于JavaScript獲取上傳進(jìn)度的幾種方式的文章就介紹到這了,更多相關(guān)JavaScript獲取上傳進(jìn)度內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論