flv.js 1.0 源碼學(xué)習(xí)(二)

二、IO

io-controller.js-IOController類-IO控制器

IOController屬性
  1. 屬性分為基本信息、暫存區(qū)信息、加載器信息、數(shù)據(jù)信息、速率信息、IO 狀態(tài)信息、事件處理器

    • 1.1 基本信息 TAG 用來描述當(dāng)前構(gòu)造器名稱、_config 接收用戶自定義配置、_extraData 是提取的數(shù)據(jù)(這塊1.0 版本只在轉(zhuǎn)碼控制器里用了)
      • 1.1.1 _extraData 作為讀寫屬性 extraData 暴露
    • 1.2 暫存區(qū),_stashInitialSize 是初始大小,如果非實時流 384K,否則512K,_stashUsed 是已使用空間,_stashSize 是真實大小,還有 _bufferSize 3M 緩存區(qū)大小,對應(yīng)的還有 _stashBuffer 暫存緩存和 _stashByteStart 暫存起點,可以通過 config.enableStashBuffer 控制 _enableStash 是否開啟暫存
    • 1.3 加載器信息只有 _loader 加載器實例、_loaderClass 加載器類型、_seekHandler 搜索處理器
      • 1.3.1 _loader.status 關(guān)聯(lián)實例只讀屬性 status
      • 1.3.2 _loader.currentSpeed 關(guān)聯(lián)實例讀寫屬性 currentSpeed
      • 1.3.3 _loader.type 關(guān)聯(lián)實例讀寫屬性 loaderType
    • 1.4 數(shù)據(jù)信息有 _dataSource 原始數(shù)據(jù)源、_isWebSocketURL 是否是 ws 協(xié)議、_refTotalLength 原數(shù)據(jù)大小、_totalLength 數(shù)據(jù)總長度、_fullRequestFlag 請求全部標(biāo)志位、_currentRange 當(dāng)前的數(shù)據(jù)范圍
      • 1.4.1 _dataSource.currentUrl 關(guān)聯(lián)實例只讀屬性 currentUrl
    • 1.5 速率信息有 _speed 速率、_speedNormalized 標(biāo)準(zhǔn)速率、_speedSampler 速率計算器、_speedNormalizeList 常規(guī)速率表
    • 1.6 IO 狀態(tài)信息有 _isEarlyEofReconnecting 是否過早結(jié)束、_paused 是否暫停、_resumeFrom 恢復(fù)點
    • 1.7 事件處理器有 _onDataArrival 數(shù)據(jù)抵達(dá)、_onSeeked 搜索、_onError 出錯、_onComplete 完成、_onRecoveredEarlyEof 過早結(jié)束
      • 1.7.1 這五個屬性都有相應(yīng)的實例讀寫屬性
  2. 構(gòu)造函數(shù)里執(zhí)行了選擇搜索處理函數(shù)、選擇加載器、創(chuàng)建加載器的操作


    IOController方法
  3. 外部方法分為獲取狀態(tài)的、控制狀態(tài)的、操作數(shù)據(jù)的

    • 3.1 獲取狀態(tài)的有 isWorking 和 isPaused
      • 3.1.1 isPaused() 其實就是返回 this._paused 的值
      • 3.1.2 isWorking() 有三點要求:當(dāng)前實例存在加載器、當(dāng)前實例加載器正常運行、當(dāng)前實例沒有暫停
    • 3.2 控制狀態(tài)的有 open、pause、resume、abort、destroy
      • 3.2.1 open(optionalFrom) 用來從一個起點開始加載數(shù)據(jù)
        • 3.2.1.1 設(shè)置當(dāng)前實例的當(dāng)前范圍為 0 到 -1
        • 3.2.1.2 將實例的當(dāng)前范圍起點設(shè)置為傳入的起點,如果未傳入?yún)?shù),設(shè)置請求全部標(biāo)志位為真
        • 3.2.1.3 重置當(dāng)前實例的速率計算器
        • 3.2.1.4 打開當(dāng)前實例的加載器
      • 3.2.2 pause() 用來暫停加載數(shù)據(jù)
        • 3.2.2.1 如果當(dāng)前實例處于工作中// 沒寫否則的情況啊,有點簡略
        • 3.2.2.2 強行終止當(dāng)前實例的加載器
        • 3.2.2.3 如果當(dāng)前實例的已使用暫存區(qū)不為空
          • 3.2.2.3.1 將實例的恢復(fù)點設(shè)置為暫存區(qū)起點
          • 3.2.2.3.2 將實例的當(dāng)前范圍的結(jié)尾設(shè)置為為暫存區(qū)起點 - 1
        • 3.2.2.3 否則,將當(dāng)前實例的恢復(fù)點設(shè)置為當(dāng)前范圍的結(jié)尾 + 1
        • 3.2.2.4 設(shè)置實例的已使用暫存區(qū)為空
        • 3.2.2.5 設(shè)置實例的暫存區(qū)起點為 0
        • 3.2.2.6 設(shè)置實例的暫停屬性為 true
      • 3.2.3 resume() 用來恢復(fù)暫停加載的實例
        • 3.2.3.1 如果當(dāng)前實例處于暫停中
        • 3.2.3.2 設(shè)置實例的暫停屬性為 false
        • 3.2.3.3 將實例的恢復(fù)點存儲到一個 bytes 變量里,然后設(shè)為 0
        • 3.2.3.4 將 bytes 傳入內(nèi)部搜索方法中
      • 3.2.4 abort() 用來終止加載
        • 3.2.4.1 終止當(dāng)前實例的加載器
        • 3.2.4.2 如果實例是暫停的,將暫停屬性設(shè)為 false,并將恢復(fù)點設(shè)置為 0
      • 3.2.5 destroy() 用來銷毀當(dāng)前實例
        • 3.2.5.1 如果當(dāng)前實例的加載器處于工作中,終止此加載器
        • 3.2.5.2 銷毀當(dāng)前實例的加載器,清空構(gòu)造函數(shù)初始化的哪些變量


          3.2.5.2
    • 3.3 操作數(shù)據(jù)的有 seek、updateUrl
      • 3.3.1 seek(bytes) 用來搜索特定的一段數(shù)據(jù)
        • 3.3.1.1 設(shè)置實例的暫停屬性為 false
        • 3.3.1.2 設(shè)置實例的已用暫存區(qū)為 0
        • 3.3.1.3 設(shè)置實例的暫存區(qū)起點為 0
        • 3.3.1.4 將 bytes 傳入內(nèi)部搜索方法中
      • 3.3.2 updateUrl(url) 用來更新數(shù)據(jù)源的 URL
        • 3.3.2.1 這個方法還沒完善
  4. 內(nèi)部方法分為數(shù)據(jù)有關(guān)、操作加載器、操作暫存區(qū)、事件處理

    • 4.1 數(shù)據(jù)有關(guān)的有 _selectSeekHandler、_internalSeek、_normalizeSpeed、_dispatchChunks
      • 4.1.1 _selectSeekHandler() 用來選擇搜索處理函數(shù)
        • 4.1.1.1 根據(jù)實例的配置的搜索類型,從三種:range、param、custom 處理函數(shù)選擇一個
        • 4.1.1.2 如果搜索類型是 range,實例化一個 RangeSeekHandler 賦給實例的搜索處理函數(shù),傳入實例配置的范圍是否從零開始屬性
        • 4.1.1.2 如果搜索類型是 param
          • 4.1.1.2.1 初始化參數(shù)起點,為實例配置的參數(shù)起點值或 bstart
          • 4.1.1.2.2 初始化參數(shù)終點,為實例配置的參數(shù)終點值或 bend
          • 4.1.1.2.3 實例化一個 ParamSeekHandler 賦給實例的搜索處理函數(shù),傳入?yún)?shù)起點和終點
        • 4.1.1.3 如果搜索類型是 custom
          • 4.1.1.3.1 如果實例配置的自定義搜索處理函數(shù)無效,報錯
          • 4.1.1.3.2 實例化一個自定義搜索處理函數(shù)實例 賦給實例的搜索處理函數(shù)
        • 4.1.1.4 否則報不合法的參數(shù)錯
      • 4.1.2 _internalSeek(bytes, dropUnconsumed) 用來從特定時間點加載數(shù)據(jù)
        • 4.1.2.1 如果實例的加載器還在工作,終止加載器
        • 4.1.2.2 丟棄未消費數(shù)據(jù)地刷新暫存區(qū)
        • 4.1.2.3 銷毀實例的加載器
        • 4.1.2.4 新建一個請求范圍,起點是傳入的 bytes,終點是 -1
        • 4.1.2.5 設(shè)置實例的當(dāng)前數(shù)據(jù)范圍,起點是請求范圍的起點,終點是 -1
        • 4.1.2.6 清空實例的速率、速率計算器
        • 4.1.2.7 初始化實例的暫存區(qū)大小
        • 4.1.2.8 創(chuàng)建一個新的加載器
        • 4.1.2.9 調(diào)用新加載器的 open 方法,傳入數(shù)據(jù)源和請求范圍
        • 4.1.2.10 如果實例對搜索事件有處理函數(shù),調(diào)用之
      • 4.1.3 _normalizeSpeed(input) 用來確定加載速度,使用了二分法,類似滑動窗口思想
        • 4.1.3.1 獲取常規(guī)速率表,采用二分法確認(rèn)輸入?yún)?shù) input 應(yīng)該在表中的哪個位置
        • 4.1.3.2 返回常規(guī)速率表那個位置的值(比實際值偏?。?/li>
      • 4.1.4 _dispatchChunks(chunks, byteStart) 是分派加載完數(shù)據(jù)的函數(shù),參數(shù)為數(shù)據(jù)塊和數(shù)據(jù)起點
        • 4.1.4.1 將實例的當(dāng)前范圍的終點設(shè)置為數(shù)據(jù)起點 + 數(shù)據(jù)塊大小 - 1
        • 4.1.4.2 調(diào)用實例的數(shù)據(jù)到達(dá)事件處理函數(shù)
    • 4.2 操作加載器的有 _selectLoader、_createLoader
      • 4.2.1 _selectLoader() 用來選擇加載器
        • 4.2.1.1 如果實例有 ws 協(xié)議,設(shè)置實例的加載器類型為 WebSocketLoader
        • 4.2.1.1 如果支持 fetch 流,設(shè)置實例的加載器類型為 FetchStreamLoader
        • 4.2.1.1 如果支持火狐,設(shè)置實例的加載器類型為 MozChunkedLoader
        • 4.2.1.1 如果支持通用加載器,設(shè)置實例的加載器類型為 RangeLoader
        • 4.2.1.1 否則,報運行時的瀏覽器不支持二進(jìn)制響應(yīng)數(shù)據(jù)錯
      • 4.2.2 _createLoader() 用來創(chuàng)建加載器 我覺得這里 bind 多余了
        • 4.2.2.1 根據(jù)加載器類型,將搜索處理器作為參數(shù),實例化一個加載器,賦給實例的加載器
        • 4.2.2.2 如果實例的加載器的需要暫存緩存為 false,就將實例的是否開啟暫存設(shè)置為 false
        • 4.2.2.3 將實例的加載器的事件處理函數(shù)和實例的事件處理函數(shù)關(guān)聯(lián)起來


          4.2.2.3
  • 4.3 操作暫存區(qū)的有 _expandBuffer、_adjustStashSize、_flushStashBuffer
    • 4.3.1 _expandBuffer(expectedBytes) 用來擴(kuò)展緩存,借鑒了滑動窗口思想
      • 4.3.1.1 創(chuàng)建新緩存大小,初始值為暫存區(qū)大小
      • 4.3.1.2 只要新緩存大小 + 1M 小于 expectedBytes,就將新緩存大小翻倍
      • 4.3.1.3 給新緩存大小加 1M
      • 4.3.1.4 如果新緩存大小等于實例緩存大小,結(jié)束
      • 4.3.1.5 創(chuàng)建新緩存,初始化為新緩存大小那么大的一個二進(jìn)制數(shù)組
      • 4.3.1.6 如果實例的已使用的暫存區(qū)不為空
        • 4.3.1.6.1 創(chuàng)建一個老暫存二進(jìn)制數(shù)組,類型為 Uint8Array,指向?qū)嵗臅捍鎱^(qū)緩存,開始于字節(jié)0,長度為實例的已使用的暫存區(qū)大小
        • 4.3.1.6.2 創(chuàng)建一個新暫存二進(jìn)制數(shù)組,類型為 Uint8Array,指向新緩存,開始于字節(jié)0,長度為新緩存大小
        • 4.3.1.6.3 拷貝老暫存數(shù)組到新暫存數(shù)組
      • 4.3.1.7 將實例的暫存區(qū)緩存設(shè)置為新緩存
      • 4.3.1.8 將實例的緩存大小設(shè)置為新緩存大小
    • 4.3.2 _adjustStashSize(normalized) 用來調(diào)整暫存區(qū)大小
      • 4.3.2.1 創(chuàng)建 KB 級的暫存區(qū)大小,初始值為 0
      • 4.3.2.2 如果實例配置的實時流屬性為 true
        • 4.3.2.2.1 將 KB 級的暫存區(qū)大小設(shè)置為 normalized
      • 4.3.2.2 否則
        • 4.3.2.2.1 如果 normalized 小于 512,將 KB 級的暫存區(qū)大小設(shè)置為 normalized
        • 4.3.2.2.1 如果 normalized 在 [512,1024] 中,將 KB 級的暫存區(qū)大小設(shè)置為 normalized 的 - 1.5 倍
        • 4.3.2.2.1 否則,將 KB 級的暫存區(qū)大小設(shè)置為 normalized 的 2 倍
      • 4.3.2.3 如果 KB 級的暫存區(qū)大小大于 8192,就校正 KB 級的暫存區(qū)大小為 8192
      • 4.3.2.4 創(chuàng)建緩存大小,初始值為暫存區(qū)大小 + 1M
      • 4.3.2.5 如果實例的緩存大小小于緩存大小,給實例緩存擴(kuò)展緩存大小那么多
      • 4.3.2.6 將實例的暫存區(qū)大小設(shè)置為暫存區(qū)大小
    • 4.3.3 _flushStashBuffer(dropUnconsumed) 用來刷新暫存區(qū)和緩存
      • 4.3.3.1 如果實例的已使用緩存區(qū)不為空
        • 4.3.3.1.1 創(chuàng)建緩存,初始化為實例的暫存區(qū)緩存從 0 到已使用緩存大小
        • 4.3.3.1.2 創(chuàng)建已消費長度,初始化為加載完緩存(從實例的暫存起點)后的處理函數(shù)返回的結(jié)果
        • 4.3.3.1.3 創(chuàng)建剩余長度,初始化為緩存占據(jù)的內(nèi)存字節(jié)長度 - 已消費長度
        • 4.3.3.1.4 如果已消費長度小于緩存占據(jù)的內(nèi)存字節(jié)長度
          • 4.3.3.1.4.1 如果要丟棄未消費數(shù)據(jù)(dropUnconsumed 為 true),打印一句日志告訴用戶丟棄了多少剩余長度的數(shù)據(jù)
          • 4.3.3.1.4.1 否則
            • 4.3.3.1.4.1.1 如果已消費長度大于 0
              • 4.3.1.4.1.1.1 創(chuàng)建暫存二進(jìn)制數(shù)組,Uint8Array 類型,指向?qū)嵗臅捍鎱^(qū)緩存,開始于字節(jié)0,長度為實例的緩存大小
              • 4.3.1.4.1.1.2 創(chuàng)建剩余二進(jìn)制數(shù)組,Uint8Array 類型,指向?qū)嵗臅捍鎱^(qū)緩存,開始于已消費長度
              • 4.3.1.4.1.1.3 拷貝剩余數(shù)組到暫存區(qū)數(shù)據(jù)中
              • 4.3.1.4.1.1.4 設(shè)置實例的已使用暫存區(qū)大小為剩余數(shù)組的內(nèi)存字節(jié)長度
              • 4.3.1.4.1.1.5 給實例的暫存起點增加已消費長度
            • 4.3.3.1.4.1.2 返回 0
        • 4.3.3.1.5 設(shè)置實例的已使用暫存區(qū)大小為 0
        • 4.3.3.1.6 設(shè)置實例的暫存區(qū)起點為 0
        • 4.3.3.1.7 返回剩余長度
      • 4.3.3.1 否則,返回 0
  • 4.4 事件處理有 _onContentLengthKnown、_onLoaderChunkArrival、_onLoaderComplete、_onLoaderError
    • 4.4.1 _onContentLengthKnown(contentLength) 處理已知內(nèi)容長度事件
      • 4.4.1.1 如果 contentLength 存在并且實例的全請求標(biāo)志為真
        • 4.4.1.1.1 設(shè)置實例的數(shù)據(jù)總長度為 contentLength
        • 4.4.1.1.2 設(shè)置實例的全請求標(biāo)志為假
    • 4.4.2 _onLoaderChunkArrival(chunk, byteStart, receivedLength) 處理數(shù)據(jù)到達(dá)事件
      • 4.4.2.1 如果實例沒有處理數(shù)據(jù)到達(dá)事件的函數(shù),報錯
      • 4.4.2.2 如果實例的暫停屬性為 true,結(jié)束
      • 4.4.2.3 如果實例的過早結(jié)束屬性為 true,將之設(shè)置為 false。如果實例存在接收過早結(jié)束函數(shù),調(diào)用之。
      • 4.4.2.4 實例的速率計算器增加 chunk 字節(jié)長度那么多的字節(jié)
      • 4.4.2.5 根據(jù)速率動態(tài)調(diào)整存儲緩沖區(qū)大小


        4.4.2.5
      • 4.4.2.6 如果實例的允許暫存區(qū)為 false
        • 4.4.2.6.1 如果實例的已使用暫存區(qū)為空
          • 4.4.2.6.1.1 直接將數(shù)據(jù)分派給消費者
          • 4.4.2.6.1.2 如果已消費數(shù)據(jù)長度小于 chunk 字節(jié)長度
            • 4.4.2.6.1.2.1 創(chuàng)建未消費長度,初始值為 chunk 字節(jié)長度 - 已消費長度
            • 4.4.2.6.1.2.2 如果未消費長度大于實例的緩存大小,擴(kuò)展實例緩存
            • 4.4.2.6.1.2.3 創(chuàng)建暫存區(qū)數(shù)組,Uint8Array 類型,指向?qū)嵗臅捍鎱^(qū)緩存,起點為 0,長度為實例的緩存大小
            • 4.4.2.6.1.2.4 創(chuàng)建已消費數(shù)組,Uint8Array 類型,指向 chunk,起點為已消費長度,拷貝到暫存區(qū)數(shù)組里去
            • 4.4.2.6.1.2.5 將實例的已使用暫存區(qū)長度加上剩余長度
            • 4.4.2.6.1.2.6 設(shè)置暫存區(qū)起點為 byteStart + 已消費長度
        • 4.4.2.6.1 否則將 chunk 合并到暫存區(qū)緩存中,并將暫存區(qū)緩存分派給使用者。
          • 4.4.2.6.1.1 如果實例的已使用暫存區(qū)大小 + chunk 字節(jié)長度 > 實例的緩存大小,擴(kuò)展實例緩存
          • 4.4.2.6.1.2 創(chuàng)建暫存區(qū)數(shù)組,Uint8Array 類型,指向?qū)嵗臅捍鎱^(qū)緩存,起點為 0,長度為實例的緩存大小
          • 4.4.2.6.1.3 創(chuàng)建 chunk 數(shù)組,Uint8Array 類型,指向 chunk ,拷貝到暫存區(qū)數(shù)組里去
          • 4.4.2.6.1.4 將實例的已使用暫存區(qū)長度加上 chunk 字節(jié)長度
          • 4.4.2.6.1.5 創(chuàng)建已消費長度,初始化為實例暫存緩存從 0 到實例已使用暫存區(qū)長度那么多,分派之
          • 4.4.2.6.1.6 如果已消費長度小于實例已使用暫存區(qū)長度且已消費長度 > 0
            • 4.4.2.6.1.6.1 新建剩余數(shù)組,Uint8Array 類型,指向?qū)嵗臅捍婢彺妫瘘c為已消費長度
            • 4.4.2.6.1.6.2 拷貝剩余數(shù)組到暫存數(shù)組去
          • 4.4.2.6.1.7 將實例的已使用暫存長度減去已消費長度
          • 4.4.2.6.1.8 將暫存區(qū)起點加上已消費長度
      • 4.4.2.6 否則
        • 4.4.2.6.1 如果實例的已用暫存區(qū)為空且實例的暫存區(qū)起點為 0,將實例的暫存區(qū)設(shè)為 byteStart
        • 4.4.2.6.2 如果實例的已用暫存區(qū)長度 + chunk 參數(shù)字節(jié)長度 <= 實例的暫存區(qū)長度
          • 4.4.2.6.2.1 創(chuàng)建暫存區(qū)數(shù)組,Uint8Array 類型,指向?qū)嵗臅捍鎱^(qū)緩存,起點為 0,長度為實例的暫存區(qū)大小
          • 4.4.2.6.2.2 新建 chunk 數(shù)組,Uint8Array 類型,指向 chunk 參數(shù),起點為已用暫存區(qū)長度,拷貝到暫存區(qū)數(shù)組去
          • 4.4.2.6.2.3 將實例的已用暫存長度加上 chunk 參數(shù)的字節(jié)長度
        • 4.4.2.6.2 否則,chunk 太大了,發(fā)送整個暫存區(qū)緩存,并保留數(shù)據(jù),然后將塊添加到暫存區(qū)緩存
          • 4.4.2.6.2.1 創(chuàng)建暫存區(qū)數(shù)組,Uint8Array 類型,指向?qū)嵗臅捍鎱^(qū)緩存,起點為 0,長度為緩存大小
          • 4.4.2.6.2.2 如果實例的已用暫存不為空
            • 4.4.2.6.2.2.1 創(chuàng)建緩存,初始值為實例暫存緩存從 0 到實例的已用暫存長度這么多
            • 4.4.2.6.2.2.2 創(chuàng)建已消費長度,初始值為從實例暫存起點分發(fā)緩存這么多
            • 4.4.2.6.2.2.3 如果已消費長度 < 緩存字節(jié)長度
              • 4.4.2.6.2.2.3.1 如果已消費長度 > 0
                • 4.4.2.6.2.2.3.1.1 創(chuàng)建剩余數(shù)組,Uint8Array 類型,指向緩存,起點為已消費長度,拷貝到暫存區(qū)數(shù)組去
                • 4.4.2.6.2.2.3.1.2 將實例已用暫存長度設(shè)為剩余數(shù)組字節(jié)長度
                • 4.4.2.6.2.2.3.1.3 將暫存起點加上消費長度
              • 4.4.2.6.2.2.3.1 否則,將實例已用暫存長度設(shè)為 0,將暫存起點加上消費長度
            • 4.4.2.6.2.2.4 如果實例已用暫存長度 + chunk 字節(jié)長度 > 實例緩存大小
              • 4.4.2.6.2.2.4.1 擴(kuò)展緩存
              • 4.4.2.6.2.2.4.2 重設(shè)暫存區(qū)數(shù)組,Uint8Array 類型,指向?qū)嵗臅捍鎱^(qū)緩存,起點為 0,長度為緩存大小
            • 4.4.2.6.2.2.5 創(chuàng)建 chunk 數(shù)組,Uint8Array 類型,指向 chunk ,起點為實例已用暫存長度,拷貝到暫存區(qū)數(shù)組去
            • 4.4.2.6.2.2.6 將實例已用暫存長度加上 chunk 的字節(jié)長度
          • 4.4.2.6.2.2 否則,存儲緩沖區(qū)為空,但是 chunk 大小 > 暫存區(qū)大小,直接派發(fā)塊并保留數(shù)據(jù)
            • 4.4.2.6.2.2.1 創(chuàng)建已消費長度,初始值為從 byteStart 分發(fā) chunk 這么多的數(shù)據(jù)
            • 4.4.2.6.2.2.2 如果已消費長度 < chunk 字節(jié)長度
              • 4.4.2.6.2.2.2.1 創(chuàng)建剩余長度,初始值為 chunk 字節(jié)長度 - 已消費長度
              • 4.4.2.6.2.2.2.2 如果剩余長度 > 實例緩存大小,擴(kuò)展緩存,并創(chuàng)建暫存區(qū)數(shù)組,Uint8Array 類型,指向?qū)嵗臅捍鎱^(qū)緩存,起點為 0,長度為緩存大小
              • 4.4.2.6.2.2.2.3 創(chuàng)建 chunk 數(shù)組,Uint8Array 類型,指向 chunk ,起點為已消費長度,拷貝到暫存區(qū)數(shù)組去
              • 4.4.2.6.2.2.2.4 將實例已使用暫存區(qū)長度加上剩余長度
              • 4.4.2.6.2.2.2.5 將實例暫存區(qū)起點設(shè)為 byteStart + 消費長度
    • 4.4.3 _onLoaderComplete(from, to) 處理數(shù)據(jù)加載完成事件
      • 4.4.3.1 以丟棄未消費數(shù)據(jù)模式刷新暫存區(qū)和緩存
      • 4.4.3.2 如果實例的完成事件有監(jiān)聽函數(shù),調(diào)用之,傳入實例的提取數(shù)據(jù)
    • 4.4.4 _onLoaderError(type, data) 處理數(shù)據(jù)加載錯誤事件
      • 4.4.4.1 以保留未消費數(shù)據(jù)模式刷新暫存區(qū)和緩存
      • 4.4.4.2 如果實例的過早結(jié)束屬性為 true
        • 4.4.4.2.1 設(shè)置實例的過早結(jié)束屬性為 false
        • 4.4.4.2.2 設(shè)置 type 為加載器錯誤的接收過早結(jié)束
      • 4.4.4.3 判斷 type
        • 4.4.4.3.1 type 是過早結(jié)束
          • 4.4.4.3.1.1 如果實例配置的實時流屬性為 false
            • 4.4.4.3.1.1.1 如果實例的數(shù)據(jù)總長度存在
              • 4.4.4.3.1.1.1.1 創(chuàng)建下一個起點,初始化為實例的當(dāng)前范圍的終點 + 1
              • 4.4.4.3.1.1.1.2 如果下一個起點小于實例的數(shù)據(jù)總長度,設(shè)置實例的過早結(jié)束屬性為 true,調(diào)用不丟棄未消費數(shù)據(jù)的內(nèi)部搜索方法,傳入下一個起點
              • 4.4.4.3.1.1.1.3 結(jié)束
          • 4.4.4.3.1.2 設(shè)置 type 為加載器錯誤的接收過早結(jié)束
        • 4.4.4.3.1 type 是接收過早結(jié)束、連接超時、HTTP 狀態(tài)碼無效、其他:跳過
      • 4.4.4.4 如果實例的錯誤事件有監(jiān)聽函數(shù),調(diào)用之,傳入 type 和 data
      • 4.4.4.4 否則報 IOException 錯誤

疑問:緩存區(qū)和暫存區(qū)有啥關(guān)系?為什么不把暫存區(qū)的屬性方法單獨抽象個類?

range-seek-handler.js-RangeSeekHandler類-range法查找處理器

默認(rèn)搜索處理函數(shù)。


RangeSeekHandler
  1. 屬性:_zeroStart,搜索范圍是否從 0 開始
  2. 方法:getConfig 獲取搜索配置,傳入 url 和 range 參數(shù)
    • 2.1 新建一個 headers 對象,初始化為 {}
    • 2.2 如果 range 的起點不為 0 或者終點不為 -1
      • 2.2.1 如果 range 的終點不為 -1,headers['Range'] 為 range 的起點到 range 的終點
      • 2.2.1 否則,headers['Range'] 只考慮 range 的起點
    • 2.2 如果搜索范圍需要從 0 開始,headers['Range'] 考慮起點為 0
    • 2.3 返回一個對象,鍵分別為 url 和 headers

操作 headers

param-seek-handler.js-ParamSeekHandler類-param法查找處理器

我猜這種是針對B站特有的一種搜索函數(shù)。


ParamSeekHandler
  1. 屬性:_startName 搜索范圍起點,_endName 搜索范圍終點
  2. 方法:getConfig 獲取搜索配置,傳入 baseUrl 和 range 參數(shù)
    • 2.1 新建一個 headers 對象,初始化為 {}
    • 2.2 如果 range 的起點不為 0 或者終點不為 -1
      • 2.2.1 如果 url 沒有 ?,url 加上 ?
      • 2.2.1 否則 url 加上 &
      • 2.2.2 url 拼接 實例的起點=range起點
      • 2.2.3 如果 range 終點不等于 -1,url 拼接實例的終點=range終點
      • 2.2.4 返回一個對象,鍵分別為 url 和 headers

操作 url

speed-sampler.js-SpeedSampler類-實時網(wǎng)速計算器

SpeedSampler
  1. 屬性有 _firstCheckpoint 首次檢查點、_lastCheckpoint 結(jié)尾檢查點、_intervalBytes 間隔字節(jié)數(shù)、_totalBytes 總字節(jié)數(shù)、_lastSecondBytes 最后一秒字節(jié)數(shù)、_now 獲取當(dāng)前時間函數(shù)(默認(rèn) performance.now,替補 Date.now)

  2. 只讀屬性:

    • 2.1 get currentKBps() 當(dāng)前速率,值為 1000 * 1024 * 間隔字節(jié)數(shù)/(當(dāng)前時間 - 結(jié)尾檢查點),但是為了防止大數(shù)溢出,還是(間隔字節(jié)數(shù) /(當(dāng)前時間 - 結(jié)尾檢查點)/ 1000 )/ 1024
    • 2.2 get lastSecondKBps() 最后速率
      • 2.2.1 如果實例的最后一秒字節(jié)數(shù)不為 0,返回實例最后一秒字節(jié)數(shù) / 1024
      • 2.2.1 否則
        • 2.2.1.1 如果實例當(dāng)前時間 - 實例結(jié)尾檢查點 >= 500,返回實例當(dāng)前速率
        • 2.2.1.1 否則,返回 0
    • 2.3 get averageKBps() 平均速率,值為(總字節(jié)數(shù) /(當(dāng)前時間 - 首次檢查點)/ 1000 )/ 1024

這里要說一句,時間算完要除 1000,單位就從毫秒變成了秒,再套用經(jīng)典公式 v = sum / time,就得到了網(wǎng)絡(luò)傳輸速率,只不過單位是字節(jié),一般我們是以 K 表示,所以還要除 1024

  1. 方法
    • 3.1 reset() 重置,其實就是讓五個實例屬性值全變成 0
    • 3.2 addBytes(bytes) 增加字節(jié)數(shù),傳入 bytes 參數(shù)
      • 3.2.1 如果實例首次檢查點為 0
        • 3.2.1.1 將實例首次檢查點設(shè)為現(xiàn)在
        • 3.2.1.2 將實例結(jié)尾檢查點設(shè)為實例首次檢查點
        • 3.2.1.3 將實例間隔字節(jié)數(shù)加上 bytes
        • 3.2.1.4 將實例總字節(jié)數(shù)加上 bytes
      • 3.2.1 如果當(dāng)前時間 - 實例結(jié)尾檢查點 < 1000
        • 3.2.1.1 將實例間隔字節(jié)數(shù)加上 bytes
        • 3.2.1.2 將實例總字節(jié)數(shù)加上 bytes
      • 3.2.1 否則
        • 3.2.1.1 將實例最后一秒字節(jié)數(shù)設(shè)為實例間隔字節(jié)數(shù)
        • 3.2.1.2 將實例間隔字節(jié)數(shù)設(shè)為 bytes
        • 3.2.1.3 將實例總字節(jié)數(shù)加上 bytes
        • 3.2.1.4 將實例結(jié)尾檢查點設(shè)為現(xiàn)在

這個類最關(guān)鍵的方法就是 addBytes,因為在設(shè)立初始化檢查點后,每次添加字節(jié),都會更新結(jié)尾檢查點,然后計算一次速率。所以,它是一段一段算速率的。

loader.js

  1. BaseLoader類-數(shù)據(jù)加載器


    BaseLoader
    • 1.1 屬性有 _type 加載器類型、_status 加載器狀態(tài)、_needStash 是否需要暫存區(qū)、_onContentLengthKnown 已知內(nèi)容長度事件處理函數(shù)、_onDataArrival 數(shù)據(jù)抵達(dá)事件處理函數(shù)、_onError 出錯事件處理函數(shù)、_onComplete 完成事件處理函數(shù)
      • 1.1.1 加載器類型初始化為構(gòu)造函數(shù)傳入的 typeName 參數(shù),并且有對應(yīng)的實例只讀屬性 type
      • 1.1.2 加載器狀態(tài)初始化為閑置狀態(tài),并且有對應(yīng)的實例只讀屬性 status
      • 1.1.3 是否需要暫存區(qū)初始化為 false,并且有對應(yīng)的實例只讀屬性 needStash
      • 1.1.4 四個事件處理函數(shù)初始化為 null,對應(yīng)四個實例屬性
    • 1.2 方法有
      • 1.2.1. destroy() 銷毀加載器實例,就是將實例狀態(tài)設(shè)為重置,四個事件處理函數(shù)設(shè)置為 null
      • 1.2.2. isWorking() 獲取加載器運行狀態(tài),根據(jù)加載器狀態(tài)是連接中或者緩存中來判斷
      • 1.2.3. open(dataSource, range) 打開數(shù)據(jù)源開始加載,報錯---延遲到子類實現(xiàn)
      • 1.2.4. abort() 終止加載,報錯---延遲到子類實現(xiàn)
  2. LoaderStatus常量-加載器狀態(tài)

    • 2.1 kIdle 閑置
    • 2.2 kConnecting 連接中
    • 2.3 kBuffering 緩沖中
    • 2.4 kError 出錯
    • 2.5 kComplete 完成
  3. LoaderErrors-加載器錯誤

    • 3.1 OK 成功
    • 3.2 EXCEPTION 其他錯誤
    • 3.3 HTTP_STATUS_CODE_INVALID HTTP 狀態(tài)碼錯誤
    • 3.4 CONNECTING_TIMEOUT 連接超時
    • 3.5 EARLY_EOF 過早結(jié)束
    • 3.6 UNRECOVERABLE_EARLY_EOF 不可恢復(fù)的過早結(jié)束

fetch-stream-loader.js-FetchStreamLoader類-fetch加載器

FetchStreamLoader
  1. 屬性

    • 1.1 isSupported() 是否支持 fetch 流加載:瀏覽器非 IE、全局有 fetch 方法和 ReadableStream 屬性
    • 1.2 TAG 實例構(gòu)造器名稱
    • 1.3 _seekHandler 搜索處理函數(shù)
    • 1.4 _needStash 需要暫存區(qū),重寫為 true
    • 1.5 _requestAbort 請求終止標(biāo)志位,初始化為 false
    • 1.6 _contentLength 內(nèi)容長度,初始化為 null
    • 1.7 _receivedLength 已接收長度,初始化為 0
  2. 方法

    • 2.1 destroy() 銷毀實例
      • 2.1.1 如果實例處于工作中,終止加載
      • 2.1.2 執(zhí)行基類的 destroy 方法
    • 2.2 open(dataSource, range) 加載數(shù)據(jù),傳入 dataSource 和 range 兩個參數(shù)
      • 2.2.1 設(shè)置實例的數(shù)據(jù)源為 dataSource,實例的范圍為 range
      • 2.2.2 獲取實例的搜索處理函數(shù)配置(之后簡稱搜索配置)
      • 2.2.3 new 一個 Headers 實例(之后簡稱 headers)
      • 2.2.4 如果搜索配置的 headers 屬性是一個對象,遍歷這個屬性,將它自身的鍵值對添加到 headers 里
      • 2.2.5 創(chuàng)建一個參數(shù),等下 ajax 時用


        2.2.5
      • 2.2.6 如果 dataSource 的跨域?qū)傩詾?false,設(shè)置參數(shù)的模式為 same-origin
      • 2.2.7 如果 dataSource 的證書屬性為 false,設(shè)置參數(shù)的證書為 include
      • 2.2.8 設(shè)置實例的狀態(tài)為連接中
      • 2.2.9 通過 fetch 實現(xiàn) ajax,傳入搜索配置中的 url 和參數(shù)獲取響應(yīng)數(shù)據(jù)
        • 2.2.9.1 如果實例的請求終止標(biāo)志位為 true
          • 2.2.9.1.1 設(shè)置實例的請求終止標(biāo)志位為 false
          • 2.2.9.1.2 設(shè)置實例的狀態(tài)為閑置
          • 2.2.9.1.3 結(jié)束
        • 2.2.9.2 如果響應(yīng)數(shù)據(jù)接收成功且狀態(tài)碼為 2xx
          • 2.2.9.2.1 如果響應(yīng)數(shù)據(jù)頭長度不為 0 且實例存在已知內(nèi)容長度事件處理函數(shù),執(zhí)行之
          • 2.2.9.2.2 執(zhí)行抽取函數(shù),傳入通過響應(yīng)數(shù)據(jù)體的 getReader 方法獲取的對象
        • 2.2.9.2 否則
          • 2.2.9.2.1 設(shè)置實例的狀態(tài)為出錯
          • 2.2.9.2.2 如果實例存在出錯事件處理函數(shù),執(zhí)行之,傳入 HTTP 狀態(tài)碼錯誤和錯誤數(shù)據(jù)
          • 2.2.9.2.2 否則報 HTTP 狀態(tài)碼無效錯誤
        • 2.2.9.3 若捕捉到錯誤
          • 2.2.9.3.1 設(shè)置實例的狀態(tài)為出錯
          • 2.2.9.3.2 如果實例存在出錯事件處理函數(shù),執(zhí)行之,傳入其他錯誤和錯誤數(shù)據(jù)
          • 2.2.9.3.2 否則拋出錯誤
    • 2.3 abort() 終止加載器:設(shè)置當(dāng)前實例的請求終止標(biāo)志位為 true
    • 2.4 _pump(reader) 抽取數(shù)據(jù),傳入 reader 參數(shù),返回一個 Promise,為 reader 調(diào)用 read() 后的 result
      • 2.4.1 如果 result 的 done 為 true
        • 2.4.1.1 設(shè)置實例的狀態(tài)為完成
        • 2.4.1.2 如果實例存在完成事件處理函數(shù),執(zhí)行之,傳入實例范圍起點和實例范圍起點 + 實例接受數(shù)據(jù)長度 - 1
      • 2.4.1 否則
        • 2.4.1.1 如果實例的請求終止標(biāo)志位為 true
          • 2.4.1.1.1 設(shè)置實例的請求終止標(biāo)志位為 false
          • 2.4.1.1.2 設(shè)置實例的狀態(tài)為完成
          • 2.4.1.1.3 返回 reader.cancel()
        • 2.4.1.2 設(shè)置實例的狀態(tài)為緩沖中
        • 2.4.1.3 給實例的接收長度加上 result.value.buffer 的字節(jié)長度
        • 2.4.1.4 如果實例存在完成數(shù)據(jù)到達(dá)處理函數(shù),執(zhí)行之,傳入 result.value.buffer、實例范圍起點 + 實例接收長度、實例接收長度
        • 2.4.1.5 返回執(zhí)行抽取函數(shù)的結(jié)果,傳入 reader
      • 2.4.2 若捕捉到錯誤
        • 2.4.2.1 設(shè)置實例的狀態(tài)為出錯
        • 2.4.2.2 創(chuàng)建錯誤類型,初始化為 0
        • 2.4.2.3 創(chuàng)建錯誤信息,初始化為 null
        • 2.4.2.4 如果錯誤碼為 19 且 (實例內(nèi)容長度為空或?qū)嵗邮臻L度小于實例內(nèi)容長度),錯誤類型為加載器過早結(jié)束,錯誤信息同理
        • 2.4.2.4 否則錯誤類型為加載器其他錯誤,錯誤信息同理
        • 2.4.2.5 如果實例存在出錯事件處理函數(shù),執(zhí)行之,傳入錯誤類型和錯誤信息
        • 2.4.2.5 否則拋出運行時錯誤,傳入錯誤信息

websocket-loader.js-WebSocketLoader類-WebSocket實時流加載器

WebSocketLoader
  1. 屬性

    • 1.1 isSupported() 是否支持 WebSocket:全局有 WebSocket 屬性
    • 1.2 TAG 實例構(gòu)造器名稱
    • 1.3 _needStash 需要暫存區(qū),重寫為 true
    • 1.4 _requestAbort 請求終止標(biāo)志位,初始化為 false
    • 1.5 _ws WebSocket 實例,初始化為 null
    • 1.6 _receivedLength 已接收長度,初始化為 0
  2. 方法

    • 2.1 destroy() 銷毀實例
      • 2.1.1 如果實例有 WS 實例,終止數(shù)據(jù)加載
      • 2.1.2 執(zhí)行基類的 destroy 方法
    • 2.2 open(dataSource)
      • 2.2.1 new 一個 WS 實例,傳入 dataSource 的 url,保存在實例的 WS 實例屬性中
      • 2.2.2 設(shè)置實例 WS 實例的 binaryType 屬性為 arraybuffer
      • 2.2.3 對實例 WS 實例的四個事件進(jìn)行監(jiān)聽


        2.2.3
      • 2.2.4 設(shè)置實例的狀態(tài)為連接中
      • 2.2.5 若捕獲到異常
        • 2.2.5.1 設(shè)置實例的狀態(tài)為出錯
        • 2.2.5.2 如果實例存在出錯事件處理函數(shù),執(zhí)行之,傳入錯誤信息
        • 2.2.5.2 否則拋出運行時錯誤
    • 2.3 abort()
      • 2.3.1 如果實例的 WS 實例的 readyState 為 0 或者 1,就將實例的請求終止標(biāo)志位設(shè)為 true,然后關(guān)閉 WS 實例
      • 2.3.2 將實例的 WS 實例設(shè)為 null
      • 2.3.3 設(shè)置實例的狀態(tài)為完成
    • 2.4 _onWebSocketOpen(e) WS 打開事件處理函數(shù)
      • 2.4.1 設(shè)置實例的狀態(tài)為緩沖中
    • 2.5 _onWebSocketClose(e) WS 關(guān)閉事件處理函數(shù)
      • 2.5.1 如果實例的請求終止標(biāo)志位為 true,就將實例的請求終止標(biāo)志位設(shè)為 false,然后結(jié)束
      • 2.5.2 設(shè)置實例的狀態(tài)為完成
      • 2.5.3 如果實例存在完成事件處理函數(shù),執(zhí)行之,傳入 0 和 實例接收長度 - 1
    • 2.6 _onWebSocketMessage(e) WS 接收消息事件處理函數(shù)
      • 2.6.1 將實例的接收長度加上 event.data 的字節(jié)長度
      • 2.6.2 如果實例存在數(shù)據(jù)到達(dá)事件處理函數(shù),執(zhí)行之,傳入 event.data、實例接收長度
    • 2.7 _onWebSocketError(e) WS 出錯事件處理函數(shù)
      • 2.7.1 設(shè)置實例的狀態(tài)為出錯
      • 2.7.2 如果實例存在出錯事件處理函數(shù),執(zhí)行之,傳入錯誤信息
      • 2.7.2 否則拋出運行時錯誤

xhr-moz-chunked-loader.js-MozChunkedLoader類-火狐加載器

MozChunkedLoader
  1. 屬性

    • 1.1 isSupported() 是否支持火狐,核心是判斷 XMLHttpRequest 對象的響應(yīng)類型是不是 moz-chunked-arraybuffer
    • 1.2 TAG 實例構(gòu)造器名稱
    • 1.3 _seekHandler 搜索處理函數(shù)
    • 1.4 _needStash 需要暫存區(qū),重寫為 true
    • 1.5 _xhr XMLHttpRequest 實例
    • 1.6 _requestAbort 請求終止標(biāo)志位,初始化為 false
    • 1.7 _contentLength 內(nèi)容長度,初始化為 null
    • 1.8 _receivedLength 已接收長度,初始化為 0
  2. 方法

    • 2.1 destroy() 銷毀實例
      • 2.1.1 如果實例處于工作中,終止加載
      • 2.1.2 釋放實例的 XMLHttpRequest 實例
      • 2.1.3 執(zhí)行基類的 destroy 方法
    • 2.2 open(dataSource, range) 打開數(shù)據(jù)源開始加載
      • 2.2.1 設(shè)置實例的數(shù)據(jù)源為 dataSource,實例的范圍為 range
      • 2.2.2 獲取實例的搜索處理函數(shù)配置(之后簡稱搜索配置)
      • 2.2.3 new 一個 XMLHttpRequest 實例(之后簡稱 xhr),保存到實例的 XMLHttpRequest 實例
      • 2.2.4 通過 xhr 的 open 方法進(jìn)行 ajax,傳入搜索配置的 url
      • 2.2.5 設(shè)置 xhr 的 responseType 為 moz-chunked-arraybuffer
      • 2.2.6 對 xhr 的四個事件進(jìn)行監(jiān)聽 // 圖
      • 2.2.7 如果 dataSource 的證書屬性為 true,設(shè)置 xhr 的 withCredentials 屬性為 true
      • 2.2.8 如果搜索配置頭是一個對象,遍歷搜索配置頭,通過 setRequestHeader 方法將它自身的鍵值對設(shè)置到 xhr 的請求頭中
      • 2.2.9 設(shè)置實例的狀態(tài)為連接中
      • 2.2.10 啟動 xhr 連接
    • 2.3 abort() 終止加載
      • 2.3.1 設(shè)置當(dāng)前實例的請求終止標(biāo)志位為 true
      • 2.3.2 如果實例上存在 XMLHttpRequest 實例,終止之
      • 2.3.3 設(shè)置實例的狀態(tài)為完成
    • 2.4 _onReadyStateChange(e) readyState 屬性改變事件處理函數(shù)
      • 2.4.1 從 e 從獲取 xhr
      • 2.4.2 如果 xhr 的 readyState 等于 2
        • 2.4.2.1 如果 xhr 的 status 是 2xx
          • 2.4.2.1.1 設(shè)置實例的狀態(tài)為出錯
          • 2.4.2.1.2 如果實例存在出錯事件處理函數(shù),執(zhí)行之,傳入 HTTP 狀態(tài)碼錯誤和錯誤信息
          • 2.4.2.1.2 否則報 Moz HTTP 狀態(tài)碼無效錯誤
        • 2.4.2.1 否則設(shè)置實例的狀態(tài)為緩沖中
    • 2.5 _onProgress(e) 進(jìn)度事件處理函數(shù)
      • 2.5.1 如果實例的內(nèi)容長度不為空且 e.total 不為空不為零
        • 2.5.1.1 設(shè)置實例的內(nèi)容長度為 e.total
        • 2.5.1.2 如果實例存在已知內(nèi)容長度事件處理函數(shù),執(zhí)行之,傳入實例的內(nèi)容長度
      • 2.5.2 將實例的接收長度加上 e.target.response 的字節(jié)長度
      • 2.5.3 如果實例存在完成數(shù)據(jù)到達(dá)處理函數(shù),執(zhí)行之,傳入 e.target.response、實例范圍起點 + 實例接收長度、實例接收長度
    • 2.6 _onLoadEnd(e) 加載停止事件處理函數(shù)
      • 2.6.1 如果實例的請求終止標(biāo)志位為 true
        • 2.6.1.1 設(shè)置實例的請求終止標(biāo)志位為 false,結(jié)束
      • 2.6.1 如果實例狀態(tài)為出錯,結(jié)束
      • 2.6.2 設(shè)置實例狀態(tài)為完成
      • 2.6.3 如果實例存在完成事件處理函數(shù),執(zhí)行之,傳入實例范圍和實例范圍 + 實例接收范圍 - 1
    • 2.7 _onXhrError(e) 出錯事件處理函數(shù)
      • 2.7.1 設(shè)置實例狀態(tài)為出錯
      • 2.7.2 如果 e.loaded 小于實例內(nèi)容長度,錯誤類型為過早結(jié)束,錯誤信息填入過早結(jié)束文案
      • 2.7.2 否則,錯誤類型為其他錯誤
      • 2.7.3 如果實例存在出錯事件處理函數(shù),執(zhí)行之,傳入錯誤類型和錯誤信息
      • 2.7.3 否則拋出運行時錯誤

xhr-msstream-loader.js-MSStreamLoader類-IE加載器

MSStreamLoader

這里就不像之前介紹那么詳細(xì)了,畢竟只是為了兼容 IE,所以實現(xiàn)起來采用不同的方式。

  1. 屬性

    • 1.1 isSupported() IE 對 XMLHttpRequest 的支持,可以查詢 MSStream 相關(guān)資料了解
    • 1.2 TAG
    • 1.3 _seekHandler
    • 1.4 _needStash
    • 1.5 _xhr
    • 1.6 _reader MSStreamReader
    • 1.7 _totalRange IE 專用總范圍
    • 1.8 _currentRange IE 專用現(xiàn)范圍
    • 1.9 _contentLength
    • 1.10 _receivedLength
    • 1.11 _bufferLimit IE 專用緩存限制,不然會溢出
    • 1.12 _lastTimeBufferSize 上一個屬性的輔助屬性
    • 1.13 _isReconnecting IE 專用重連標(biāo)志位
  2. 方法

    • 2.1 destroy() 和火狐加載器的銷毀實例實現(xiàn)大同小異
    • 2.2 open(dataSource, range) 借助了 _internalOpen 方法,isSubrange 傳的是 false
    • 2.3 abort() 借助了 _internalAbort 方法,然后置實例狀態(tài)為完成
    • 2.4 _internalOpen(dataSource, range, isSubrange) 區(qū)別于火狐加載器就在于第三個參數(shù):可以加載子范圍的數(shù)據(jù),其它類似火狐加載器的 open 方法
    • 2.5 _internalAbort() 和火狐加載器的 abort 實現(xiàn)大同小異
    • 2.6 _xhrOnReadyStateChange(e) 和火狐加載器的 readyState 屬性改變事件處理函數(shù)實現(xiàn)大同小異
    • 2.7 _xhrOnError(e) 和火狐加載器的出錯事件處理函數(shù)實現(xiàn)大同小異
    • 2.8 _msrOnProgress(e) 區(qū)別于火狐加載器就在于會出現(xiàn)緩存太多溢出,然后重連
    • 2.9 _doReconnectIfNeeded() 重連函數(shù):先終止再打開,起點延伸已接收長度那么多
    • 2.10 _msrOnLoad(e) 和火狐加載器的加載停止事件處理函數(shù)實現(xiàn)大同小異
    • 2.11 _msrOnError(e) IE 錯誤事件處理器,和 _xhrOnError(e) 實現(xiàn)差不多

xhr-range-loader.js-RangeLoader類-通用的范圍加載器

重頭戲來了,當(dāng)前面的加載器都不支持的時候,就使用這種通用加載器。


RangeLoader
  1. 屬性

常規(guī)的如我們就不重點介紹了,主要是相較之前的加載器未出現(xiàn)過的或非常不一樣的屬性詳細(xì)介紹一下:
TAG、_seekHandler、_xhr、_requestAbort 不說

  • 1.1 isSupported() 核心是判斷 XMLHttpRequest 對象的響應(yīng)類型是不是 arraybuffer

  • 1.2 _needStash,這里重寫為 false

  • 1.3 _chunkSizeKBList 常規(guī)數(shù)據(jù)塊表,范圍從2的7次方到13次方

  • 1.4 _currentChunkSizeKB 當(dāng)前數(shù)據(jù)塊大小,初始化為 384(2的9次方)

  • 1.5 _currentSpeed 當(dāng)前加載速率

    • 1.5.1 關(guān)聯(lián)實例只讀屬性 currentSpeed
  • 1.6 _currentSpeedNormalized 當(dāng)前標(biāo)準(zhǔn)化的加載速率

  • 1.7 _zeroSpeedChunkCount 待加載數(shù)據(jù)塊數(shù)量

  • 1.8 _speedSampler 速率計算器

  • 1.9 _waitForTotalLength 是否待加載

  • 1.10 _totalLengthReceived 是否全部接收

  • 1.11 _currentRequestRange 當(dāng)前請求范圍

  • 1.12 _totalLength 總長度

  • 1.13 _contentLength 內(nèi)容長度

  • 1.14 _receivedLength 接收長度

  • 1.15 _lastTimeLoaded 當(dāng)前接收請求子范圍的長度

  1. 方法
    方法也是一樣,詳略分明
    destroy()、abort()、_internalOpen(dataSource, range)、_internalAbort()、_onXhrError(e) 不說
  • 2.1 open(dataSource, range) 加載數(shù)據(jù)
    • 2.1.1 設(shè)置實例的數(shù)據(jù)源為 dataSource
    • 2.1.2 設(shè)置實例的加載范圍為 range
    • 2.1.3 設(shè)置實例的狀態(tài)為連接中
    • 2.1.4 如果實例的已接收總長度為 0
      • 2.1.4.1 設(shè)置是否待加載為 true
      • 2.1.4.2 調(diào)用 _internalOpen,傳入實例數(shù)據(jù)源,0 到 -1 的范圍
    • 2.1.4 否則,調(diào)用 _openSubRange
  • 2.2 _openSubRange() 加載指定范圍數(shù)據(jù)
    • 2.2.1 創(chuàng)建 chunkSize 為實例當(dāng)前數(shù)據(jù)塊大小 * 1024
    • 2.2.2 創(chuàng)建 from 為實例范圍起點 + 實例接收長度
    • 2.2.3 創(chuàng)建 to 為 from + chunkSize
    • 2.2.4 如果實例的內(nèi)容長度不為空且 to - 實例范圍起點 >= 實例內(nèi)容長度,校正 to 為實例范圍起點 + 實例內(nèi)容長度 - 1
    • 2.2.5 設(shè)置實例當(dāng)前請求范圍為 {from,to}
    • 2.2.6 調(diào)用 _internalOpen,傳入實例數(shù)據(jù)源,實例當(dāng)前請求范圍
  • 2.3 _onReadyStateChange(e)
    • 2.3.1 從 e.target 中獲取 xhr
    • 2.3.2 如果 xhr.readyState 是 2
      • 2.3.2.1 如果 xhr.status 在 [200,300) 中
        • 2.3.2.1.1 如果實例的是否待加載為 true,結(jié)束
        • 2.3.2.1.2 設(shè)置實例狀態(tài)為緩沖中
      • 2.3.2.1 否則
        • 2.3.2.1.1 設(shè)置實例狀態(tài)為出錯
        • 2.3.2.1.2 如果實例存在出錯事件處理函數(shù),執(zhí)行之,傳入 HTTP 狀態(tài)碼錯誤和錯誤信息
        • 2.3.2.1.2 否則報 HTTP 狀態(tài)碼無效錯誤
  • 2.4 _onProgress(e) progress 事件的處理函數(shù)
    • 2.4.1 如果實例的內(nèi)容長度不為空
      • 2.4.1.1 初始化一個 openNextRange 為 false
      • 2.4.1.2 如果實例是否待加載為 true
        • 2.4.1.2.1 設(shè)置實例是否待加載為 false
        • 2.4.1.2.2 設(shè)置實例是否全部接收為 true
        • 2.4.1.2.3 設(shè)置 openNextRange 為 true
        • 2.4.1.2.4 調(diào)用 _internalAbort()
        • 2.4.1.2.5 如果 e.total 不為空,設(shè)置實例總長度為它
      • 2.4.1.3 計算當(dāng)前請求范圍的內(nèi)容長度(設(shè)置實例內(nèi)容長度為實例總長度或 實例范圍終點+1 - 實例范圍起點)
      • 2.4.1.4 如果 openNextRange 為 true,調(diào)用 _openSubRange,結(jié)束
      • 2.4.1.5 如果實例存在已知內(nèi)容長度事件處理函數(shù),執(zhí)行之,傳入實例的內(nèi)容長度
    • 2.4.2 創(chuàng)建 delta 為 e.loaded 實例當(dāng)前接收請求子范圍
    • 2.4.3 設(shè)置實例當(dāng)前接收請求子范圍的長度為 e.loaded
    • 2.4.4 將實例速率計算器增加 delta 這么多字節(jié)
  • 2.5 _normalizeSpeed(input),和 IOCtr 的標(biāo)準(zhǔn)化速率方法實現(xiàn)幾乎一樣
  • 2.6 _onLoad(e) load 事件的處理函數(shù)
    • 2.6.1 如果實例是否待加載為 true,設(shè)置實例是否待加載為 false,結(jié)束
    • 2.6.2 設(shè)置實例當(dāng)前接收請求子范圍的長度為 0
    • 2.6.3 獲取實例速率計算器中的最近一次的速率,保存在 KBps 里
    • 2.6.4 如果 KBps 為 0
      • 2.6.4.1 將實例待加載數(shù)據(jù)塊數(shù)量加 1
      • 2.6.4.2 如果實例待加載數(shù)據(jù)塊數(shù)量 >= 3,讓 KBps 為實例速率計算器中的平均速率
    • 2.6.5 如果 KBps 不為 0
      • 2.6.5.1 將實例當(dāng)前速率設(shè)置為 KBps
      • 2.6.5.2 如果實例當(dāng)前標(biāo)準(zhǔn)速率不等于標(biāo)準(zhǔn)化后的 KBps,校正實例標(biāo)準(zhǔn)速率為標(biāo)準(zhǔn)化后的 KBps,實例當(dāng)前數(shù)據(jù)塊大小為標(biāo)準(zhǔn)化后的 KBps
    • 2.6.6 從 e .target .response 獲取 chunk
    • 2.6.7 將實例的接收長度加上 chunk 的字節(jié)長度
    • 2.6.8 創(chuàng)建 reportComplete,初始化為 false
    • 2.6.9 如果實例的內(nèi)容長度不為空且實例接收長度 < 實例的內(nèi)容長度,調(diào)用 _openSubRange 繼續(xù)加載剩下的數(shù)據(jù)
    • 2.6.9 否則,設(shè)置 reportComplete 為 true
    • 2.6.10 如果實例存在完成數(shù)據(jù)到達(dá)處理函數(shù),執(zhí)行之,傳入 chunk、實例范圍起點 + 實例接收長度、實例接收長度
    • 2.6.11 如果 reportComplete 為 true
      • 2.6.11.1 設(shè)置實例狀態(tài)為完成
      • 2.6.11.2 如果實例存在完成事件處理函數(shù),執(zhí)行之,傳入實例范圍起點和實例范圍起點 + 實例接受數(shù)據(jù)長度 - 1

logger.js-Log類-調(diào)試工具

Log

Log 類有 2 + 5 個屬性,分別是控制全局標(biāo)簽名和是否打開全局標(biāo)簽的、console 五法的控制位(error、info、warning、debug、log)

還有五個靜態(tài)方法,就是 console 五法的封裝:

  1. 如果沒打開相應(yīng)的控制位,結(jié)束
  2. 如果 tag 不存在或者啟用了全局標(biāo)簽,tag 就設(shè)為實例全局標(biāo)簽名
  3. 創(chuàng)建 str,初始化為 [${tag}] > ${msg}
  4. 調(diào)用相應(yīng)的 console 方法打印出來
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,502評論 19 139
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 178,725評論 25 709
  • NLP就是一次引導(dǎo)人們自我覺察,做出明智選擇,發(fā)揮自身潛能,活出真實的自己,并且享受豐盛人生的喚醒旅程。而所謂從教...
    b18a04b7cafd閱讀 4,210評論 0 0
  • 文,有風(fēng)的日子 走過她 倫敦的大笨鐘 是她 懸掛在時尚的街頭 是你 執(zhí)著的鐘擺 她才走好生命的時刻 還是你 老去的...
    寧古塔詩人網(wǎng)閱讀 874評論 0 4
  • 讀書喝茶,只聞花香,不談喜悲! 有人說,最理想的生活是:在大城市奮斗,在小城市生活。走過紅塵歲月,看盡人世繁華,回...
    郝金花閱讀 356評論 0 0

友情鏈接更多精彩內(nèi)容