欧美vvv,亚洲第一成人在线,亚洲成人欧美日韩在线观看,日本猛少妇猛色XXXXX猛叫

新聞資訊

    文件分片

    在網(wǎng)上看了大半天mate60 現(xiàn)在耳朵里都是遙遙領(lǐng)先, 所以一鼓作氣給大家分享一篇大文件分片+webWorker的文章, 通過寫作這篇文章, 自己也學習到了不少知識, 比如通過js獲取電腦cpu線程, 那么話不多說直接開始

    1. 初始化, 搭設(shè)架子

    <!DOCTYPE html>
    <html lang="zh-CN">
    
    <head>
      <meta charset="UTF-8" />
      <meta name="viewport" content="width=device-width, initial-scale=1.0" />
      <meta http-equiv="X-UA-Compatible" content="ie=edge" />
      <title>大文件分片</title>
      <style></style>
    </head>
    
    <body>
      <input type="file" id="fileRef" />
      <script type="module" src="./main.js">
    
    
      </script>
    </body>
    
    </html>
    

    2. 讀取單個文件的分片, 并進行加密

    這里使用的是SparkMD5進行加密, 可自行下載并導入

    import { createChunks } from './createChunks'
    // 規(guī)定每次切片的文件大小
    const CHUNK_SIZE=1024 * 1024 * 5 // 5MB
    
    export async function cutFile (file) {
      // 生成每一個切片, 分片是耗時的所以是異步操作
      const chunk=await createChunks(file, 1, CHUNK_SIZE)
      // 等待分片完成, 就可以拿到這一個分片的信息
      console.log(chunk)
    }
    

    定義cutFile函數(shù)來進行文件切片, 并且返回該切片的開始結(jié)束, 第幾個和hash值

    import SparkMD5 from "./md5.js";
    /**
     * @param {*} file 文件
     * @param {*} index 第幾個分片
     * @param {*} chunkSize 每一個分片的大小
     */
    export function createChunks (file, index, chunkSize) {
      return new Promise((resolve, reject)=> {
        // 開始第幾個*分片的大小
        const start=index * chunkSize
        //   結(jié)束時start + 分片的大小
        const end=start + chunkSize
        const fileReader=new FileReader()
           spark.append(e.target.result);
          const files=file.slice(start, end);
        // 讀取文件的分片 讀取完成后觸發(fā)onload事件
        fileReader.onload=e=> {
          console.log(e)
          const spark=Md5(e.target.result)
          resolve({
            start,
            end,
            index,
            hash: spark.end(),
            files,
          })
        }
        // 讀取文件的分片
        fileReader.readAsArrayBuffer(file.slice(start, end))
      })
    }
    

    現(xiàn)在我們只讀到了一個分片, 但是我們需要讀取所有的分片, 所以需要計算目前這個文件需要分成多少個分片, 然后一個一個去讀

    所以可以利用文件的總大小 / 自定義定義文件切片的大小 就可以得到總切片數(shù)量

    注意這里需要向上去整, 出現(xiàn)任何的小數(shù)點都需要包含一片內(nèi)

    export async function cutFile (file) {
      // 計算文件的切片數(shù)量
      const chunks=Math.ceil(file.size / CHUNK_SIZE)
      console.log(chunks, 'chunks')
      // 生成每一個切片, 分片是耗時的所以是異步操作
      const chunk=await createChunks(file, 1, CHUNK_SIZE)
      // 等待分片完成, 就可以拿到這一個分片的信息
      console.log(chunk)
    }
    

    3. 將文件進行全部切片

    已經(jīng)拿到了文件切片的總數(shù)量, 這里就可以循環(huán), 并存儲到一個數(shù)組中即可

    export async function cutFile (file) {
      const result=[]
      // 計算文件的切片數(shù)量
      const chunks=Math.ceil(file.size / CHUNK_SIZE)
      // 生成每一個切片, 分片是耗時的所以是異步操作
      for (let i=0; i < chunks; i++) {
        const chunk=await createChunks(file, i, CHUNK_SIZE)
        // 等待分片完成, 就可以拿到這一個分片的信息
        result.push(chunk)
      }
      return result
    }
    

    此時我們根據(jù)入口函數(shù)來打印看一下結(jié)果

    文件被切割成了103分并且都保存在了一個數(shù)組中, 消耗了2.3秒

    4. 分析如何對分片進行優(yōu)化

    這里我上傳的文件是500m大小, 但是我上傳是好幾個g 一定會更加的延遲, 造成線程長時間的阻塞, 原因是這里使用到了MD5, 進行了大量的計算

    所以如何避免線程的阻塞就是優(yōu)化的關(guān)鍵, 在js中有Web Worker

    mdn的概念說: 使得在一個獨立于 Web 應(yīng)用程序主執(zhí)行線程的后臺線程中運行腳本操作成為可能。這樣做的好處是可以在獨立線程中執(zhí)行費時的處理任務(wù),使主線程(通常是 UI 線程)的運行不會被阻塞/放慢。

    關(guān)于webWoker的使用, 推薦大家看一下BEFE團隊 的一文徹底學會使用web worker

    5. 使用webWoker進行優(yōu)化

    1. 搭設(shè)架子

    首先需要定義開始線程的數(shù)量, 并且按照數(shù)量去開啟新的線程, 并搭設(shè)架子

    至于要向worker發(fā)送什么消息, 以及接收返回的值, 我們稍后分析

    // 定義線程數(shù)量
    const THREAD_COUNT=4 // 4個線程
    
    export async function cutFile (file) {
      const result=[]
      // 計算文件的切片數(shù)量
      const chunks=Math.ceil(file.size / CHUNK_SIZE)
      // 生成每一個切片, 分片是耗時的所以是異步操作
      //   for (let i=0; i < chunks; i++) {
      //     const chunk=await createChunks(file, 1, CHUNK_SIZE)
      //     // 等待分片完成, 就可以拿到這一個分片的信息
      //     result.push(chunk)
      //   }
      // 創(chuàng)建新的線程
      for (let i=0; i < THREAD_COUNT; i++) {
        const worker=new Worker('./worker.js', { type: 'module' })
        worker.postMessage(???)// 向 worker 線程發(fā)送消息
        worker.onmessage=e=> {
            // 接收到 worker 線程返回的消息
            console.log(e)
        }
      }
      return result
    }
    

    2. 計算每一個線程需要處理的切片數(shù)量

    1. 首先必須是文件file, 需要處理的文件
    2. 其次是文件的每一個尺寸, 就是定義好的CHUNK_SIZE=1024 * 1024 * 5 // 5MB
    3. 要處理的分片區(qū)間(也就是開始下標和結(jié)束的下標) 例如 103個文件 , 這里一共開啟了4個線程, 那么就需要這四個線程分別去處理103個分片文件

    以上三個條件已知的是file文件以及每一個文件的chunksize, 只有第三個是不知道的, 也就是不知道開始和結(jié)束值的分片期間

    首先需要計算每一個線程需要處理的切片數(shù)量

    const workerChunkCount=Math.ceil(切片數(shù)量 / 定義線程數(shù)量)

    開啟線程, 并計算每個線程的開始索引和結(jié)束索引, 這里需要在遍歷中通過i下標進行計算

    // 這里的worker稍后解釋如何定義, 注意這里要寫type: module 因為引入了其他模塊需要使用
    const worker=new Worker('./worker.js', { type: 'module' })   
     // 計算每個線程的開始索引和結(jié)束索引
        const startIndex=i * workerChunkCount
        let endIndex=startIndex + workerChunkCount
        // 防止最后一個線程結(jié)束索引大于文件的切片數(shù)量的總數(shù)量
        if (endIndex > chunks) {
          endIndex=chunks
        }

    最后進行發(fā)送

        // 向 worker 線程發(fā)送消息
        worker.postMessage({
          file, // 文件
          CHUNK_SIZE, // 文件大小
          startIndex, // 開始下標
          endIndex // 結(jié)束下標
        })

    完整代碼

    // 規(guī)定每次切片的文件大小
    const CHUNK_SIZE=1024 * 1024 * 5 // 5MB
    // 定義線程數(shù)量
    const THREAD_COUNT=4 // 4個線程
    
    export async function cutFile (file) {
      const result=[]
      // 計算文件的切片數(shù)量
      const chunks=Math.ceil(file.size / CHUNK_SIZE)
      // 計算每一個線程需要處理的切片數(shù)量
      const workerChunkCount=Math.ceil(chunks / THREAD_COUNT)
      // 生成每一個切片, 分片是耗時的所以是異步操作
      //   for (let i=0; i < chunks; i++) {
      //     const chunk=await createChunks(file, 1, CHUNK_SIZE)
      //     // 等待分片完成, 就可以拿到這一個分片的信息
      //     result.push(chunk)
      //   }
      // 創(chuàng)建新的線程
      for (let i=0; i < THREAD_COUNT; i++) {
        const worker=new Worker('./worker.js', { type: 'module' })
        // 計算每個線程的開始索引和結(jié)束索引
        const startIndex=i * workerChunkCount
        let endIndex=startIndex + workerChunkCount
        // 防止最后一個線程結(jié)束索引大于文件的切片數(shù)量的總數(shù)量
        if (endIndex > chunks) {
          endIndex=chunks
        }
         // 向 worker 線程發(fā)送消息
        worker.postMessage({
          file, // 文件
          CHUNK_SIZE, // 文件大小
          startIndex, // 開始下標
          endIndex // 結(jié)束下標
        })
     
        worker.onmessage=e=> {
          // 接收到 worker 線程返回的消息
          console.log(e)
        }
      }
      return result
    }

    3. 接收到 worker 線程返回的消息

    • 接收worker返回的信息, 我們需要將信息按照順序添加到result數(shù)組中,
    • 并且每次接收到一個就需要關(guān)閉掉一個線程
    • 如果線程全部完成了, 需要將result數(shù)組進行拋出
    let finishCount=0 // 記錄線程開啟的次數(shù)
    worker.onmessage=(e)=> {
            // 接收到 worker 線程返回的消息
            for (let i=startIndex; i < endIndex; i++) {
              result[i]=e.data[i - startIndex];
            }
            worker.terminate();
            finishCount++;
          // 如果記錄的開啟線程=定義的開啟線程次數(shù)
            if (finishCount===THREAD_COUNT) {
              // 通知主線程, 并返回結(jié)果
             resolve(result);
            }
       };
    

    這里使用resolve 因為需要等待, 所以需要是異步操作

    完整代碼

    export const cutFile=async (file)=> {
      return new Promise((resolve, reject)=> {
        // 規(guī)定每次切片的文件大小
        const CHUNK_SIZE=1024 * 1024 * 5; // 5MB?
        // 定義線程數(shù)量
        const THREAD_COUNT=4; // 4個線程
        let result=[];
        // 計算文件的切片數(shù)量
        const chunks=Math.ceil(file.size / CHUNK_SIZE);
        // 計算每一個線程需要處理的切片數(shù)量
        const workerChunkCount=Math.ceil(chunks / THREAD_COUNT);
        let finishCount=0; // 完成的線程數(shù)量
    
        // 生成每一個切片, 分片是耗時的所以是異步操作
        //   for (let i=0; i < chunks; i++) {
        //     const chunk=await createChunks(file, i, CHUNK_SIZE);
        //     // 等待分片完成, 就可以拿到這一個分片的信息
        //     result.push(chunk);
        //   }
        //   return result;
        // 創(chuàng)建新的線程
        for (let i=0; i < THREAD_COUNT; i++) {
          const worker=new Worker("./worker.js", {
            type: "module",
          });
          //   const worker=new Worker(worderPath)
          // 計算每個線程的開始索引和結(jié)束索引
          const startIndex=i * workerChunkCount;
          let endIndex=startIndex + workerChunkCount;
          // 防止最后一個線程結(jié)束索引大于文件的切片數(shù)量的總數(shù)量
          if (endIndex > chunks) {
            endIndex=chunks;
          }
          worker.postMessage({
            file,
            CHUNK_SIZE,
            startIndex,
            endIndex,
          });
    
          worker.onmessage=(e)=> {
            // 接收到 worker 線程返回的消息
            for (let i=startIndex; i < endIndex; i++) {
              result[i]=e.data[i - startIndex];
            }
            worker.terminate();
            finishCount++;
            if (finishCount===THREAD_COUNT) {
              // 所有線程都完成了
              // 通知主線程
              //   console.log(result);
              resolve(result);
            }
          };
        }
      });
    };
    

    4. worker文件

    因為這里開啟了worker線程, 所以需要執(zhí)行./worker的邏輯

     const worker=new Worker("./worker.js", {
            type: "module",
     });

    很顯然 這里就是將file,CHUNK_SIZE,startIndex,endIndex 這幾個有用的數(shù)據(jù)拿出來, 并且執(zhí)行讀取單個分片的方法 createChunks 這里之前已經(jīng)定義好了, 所以直接調(diào)用

    // 之前 添加worker的信息
    worker.postMessage({
            file,
            CHUNK_SIZE,
            startIndex,
            endIndex,
      });
    • 那么, 需要調(diào)用幾次createChunks 方法呢? 可以通過for循環(huán)startIndex,endIndex 來操作
    • 并且createChunks 中讀取文件是需要異步操作的, 我們希望同時全部讀取完畢后在返回, 不然就是上一個讀取完, 才會讀取下一個, 浪費了時間

    按照以上這兩點思路, 就可以寫邏輯了

    import { createChunks } from "./createChunks.js";
    
    onmessage=async (e)=> {
      const arr=[];
      const { file, CHUNK_SIZE, startIndex, endIndex }=e.data;
      // console.log(file, CHUNK_SIZE, startIndex, endIndex);
      for (let i=startIndex; i < endIndex; i++) {
        arr.push(createChunks(file, i, CHUNK_SIZE));
      }
      //  Promise.all=> 同時進行異步操作
      const chunks=await Promise.all(arr);
      // 提交線程信息
      postMessage(chunks);
    };

    看一下結(jié)果吧

    很明顯, 從之前的2秒多 多現(xiàn)在的0.2米, 速度快了10倍.

    6. Js 獲取電腦cpu的線程

    突發(fā)奇想, js能不能獲取電腦cpu的最大線程數(shù)量呢, 這樣就可以每次追求最快的速度, 現(xiàn)在已經(jīng)是晚上1點多了, 偷懶直接問了chat, 哈哈 搜了一下還真有

    這里果斷再優(yōu)化一下, 最求卓越

        // 獲取核心線程的數(shù)量
        const THREAD_COUNT=navigator.hardwareConcurrency || 4; 
        console.log(navigator.hardwareConcurrency);

    果然又快了一倍多, 美滋滋~手動撒花~~??ヽ(°▽°)ノ?

    這里附上git鏈接, 有需要的可以直接下載源碼查看

    彩蛋

    最近華為mate60的突然發(fā)布, 是讓很多人包括我在內(nèi)都欣喜不已!華為伴著遙遙領(lǐng)先和麒麟芯片再次回來了! 近年來,華為面臨了來自美國政府的技術(shù)制裁,但這并沒有阻止華為繼續(xù)前行,如同一葉輕舟,穿越千山萬水,創(chuàng)造著無盡可能. 有網(wǎng)友拍攝深夜的華為總部, 總是燈火通明, 里面的人都是頂級的優(yōu)秀人才. 不僅優(yōu)秀更是勤勞付出.

    年底爭取給 給自己換一臺華為手機. #華為 #麒麟芯片 #科技強國


    原文鏈接:https://juejin.cn/post/7273803674789953575
    著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請注明出處。

    據(jù)的獲取

    數(shù)據(jù)獲取是任何應(yīng)用程序中最重要的部分,本文將介紹,如何在react, nextjs中獲取數(shù)據(jù)

    主要有種方法可以獲取數(shù)據(jù)

    • 在服務(wù)端,用 fetch 獲取數(shù)據(jù)
    • 在客戶端,通過路由處理器獲取數(shù)據(jù)

    下面分別介紹一下這4種獲取數(shù)據(jù)的方式

    一、 fetch 獲取數(shù)據(jù)

    nextjs擴展了本機的fetch WEB API , 所以可以在服務(wù)端的每個請求上配置緩存和重新校驗的行為

    你可以在服務(wù)端組件中使用 async, await 。

    下面是獲取一個頁面的例子:

    export default async function Page() {
      const res=await fetch("https://www.helloworld.net");
      const data=await res.text();
    
      return (
        <div>
          <p>{data}</p>
        </div>
      );
    }

    默認情況下,服務(wù)端執(zhí)行異步函數(shù),fetch 是不緩存數(shù)據(jù)的(默認配置:cache: no-store)

    1.1 緩存數(shù)據(jù)

    緩存數(shù)據(jù)是提升性能一種很好的方式 ,如何配置呢 ? 比如上面的例子

    fetch('https://www.helloworld.net', { cache: 'force-cache' })

    但是在下面兩種情況下,是不緩存數(shù)據(jù)的。

    • 在服務(wù)端執(zhí)行異步函數(shù)獲取數(shù)據(jù)
    • 使用路由處理器,而且是POST請求

    1.2 緩存過期時間

    可以給緩存添加一個過期時間,如下:
    fetch('https://www.helloworld.net', { next: { revalidate: 3600 } })

    二、路由處理器

    上一節(jié)的文章中,我們就講過,nextjs 是可以直接寫接口的。

    如何寫這樣一個接口呢?步驟如下:

    • app目錄下,創(chuàng)建一個api目錄
    • app目錄下,隨便創(chuàng)建一個目錄,假如叫 chat
    • chat 目錄下,創(chuàng)建一個文件route.ts ,注意:必須叫 route.ts或者route.js

    以上步驟主要目的就是創(chuàng)建一個文件: rootDir/app/chat/route.ts

    route.ts文件中,添加如下代碼:

    import {NextApiRequest, NextApiResponse} from 'next';
    import {NextResponse} from "next/server";
    
    export const GET=async (request: NextApiRequest, context: any)=> {
      const {params}=context;
    
      try {
        return NextResponse.json({
          status: 200,
          data:{
            site:'www.helloworld.net',
            author:'待兔'
          }
        });
    
      } catch (e: any) {
        return NextResponse.json({status: 500, message: e.message});
      }
    }

    在瀏覽器中訪問http://localhost:3000/api/chat

    響應(yīng)如下:

    類比以上的操作,可以創(chuàng)建其它的api, 這個就是路由處理器,英文叫 Route Handlers , 也許我翻譯的并不準確

    以上就是經(jīng)常用的獲取數(shù)據(jù)的方式,如果對你有幫助,請點個關(guān)注轉(zhuǎn)發(fā)一下。謝謝

    個視頻來說一下js的文件讀取。剛好有同學問到,首先要說一點,對文件進行讀寫、增刪、改查一系列的操作是涉及到用戶隱私安全的。用前端語言,比方JS是不可能完全做到的。要不然寫一個網(wǎng)頁,訪問了就可以在本地電腦上面隨便新增文件,或者把電腦里面的東西全部給干了或者改了,都是一件很恐怖的事情。

    可以實現(xiàn)文件操作的語言,比方nodejs,一些后端語言,PHP、JAVA這些。這個時候要分清楚是操作哪里的文件,是客戶端還是服務(wù)器端。如果要操作客戶端的,都要獲取相應(yīng)的權(quán)限。比方手機端的應(yīng)用都會向我們拿權(quán)限。很多時候不給文件訪問的權(quán)限,比方圖庫,連相冊訪問都訪問不了,不用增刪、改查了,這些先不管它了。

    JS的文件讀取,簡單的文件讀取還是可以實現(xiàn)的。但是同樣,這里要讀取的是本地的文件,其實也需要用戶給予權(quán)限。這里要怎么做?就需要配合一個input的控件,讓用戶自己來操作。這里提供了一個按鈕,只有用戶主動去選擇了,這個行為是用戶觸發(fā)的。換言之就是得到了用戶的允許才會對文件進行讀取,不會JS自動觸發(fā)、自動讀取,那就不安全了。

    來看一下具體怎么操作。要對input添加一個onchange事件,然后執(zhí)行一個函數(shù)a1s,把事件對象傳進去,然后來寫這個函數(shù)。這里需要用到一個fileReader類,先把對象實例化出來。可以先把事件對象打印出來看一下。先把控制臺打開,然后來選擇文件。這里選擇a.txt文件,事件對象打印出來了,展開來看一下。

    里面有個target,target下面還有一個叫files,這一個下標為0的,files里面下標為0的,放的就是剛才選擇的文件a.txt,所以就要讀取用戶選擇的文件。這里是可以讀取成好幾種格式的,就把它讀成文本。

    ·要讀取什么?就是剛才給大家展開來看的target下面files的第0個,就是剛才選擇的文件a.txt,這個文件里面就隨便輸入一句話,看一下等一下可不可以把它讀取出來。這個過程是異步的,要先等它讀取。

    ·這里面還是先把事件對象打出來看一下,同樣是選擇剛才那個文件,再展開來看一下,同樣找到target,它里面有一個result,大家看到?jīng)]有,result里面保存的就是讀取的文件里面的內(nèi)容,這樣就可以讀取到文件的內(nèi)容了。

    ·比方這里直接把讀取到的內(nèi)容輸出來,沒有問題,這個內(nèi)容獲取到了。當然除了讀這種txt的文本,讀個json,甚至讀個圖片也可以,就來讀個圖片試一下。讀圖片這里就不是讀成text,讀成base64。

    ·這次就來選擇一張圖片,這里就把讀取到的結(jié)果輸出來了,可以復制一下,這個是base64,可以把剛才復制的那一串在地址欄里面回車,這張圖片就出來了,是可以讀取到這張圖片的。

    ·可以用讀取到的圖片做一些預(yù)覽圖之類的,這個圖片有點大,給它改小一點。JS獲取到img,然后設(shè)置一下它的src,把result賦值給它。

    ·現(xiàn)在還沒有預(yù)覽圖,可以手動來選擇一張,這里隨便選擇一張圖片,這個圖片就讀取到了,然后換一張圖片也可以,另外再選擇另外一張,都是可以正常讀取的。

    這個視頻就簡單給大家說了一下JS的文件讀取,感謝大家的收看。

網(wǎng)站首頁   |    關(guān)于我們   |    公司新聞   |    產(chǎn)品方案   |    用戶案例   |    售后服務(wù)   |    合作伙伴   |    人才招聘   |   

友情鏈接: 餐飲加盟

地址:北京市海淀區(qū)    電話:010-     郵箱:@126.com

備案號:冀ICP備2024067069號-3 北京科技有限公司版權(quán)所有