自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

優(yōu)雅的處理Window.Fun可能不存在的情況

系統(tǒng) Windows
在做一個Web JS SDK(A)時,內(nèi)部會用到另一個Web JS SDK(B)的方法。(文中后續(xù)用A/B代替兩者)

[[425592]]

本文轉(zhuǎn)載自微信公眾號「粥里有勺糖」,作者粥里有勺糖。轉(zhuǎn)載本文請聯(lián)系粥里有勺糖公眾號。

背景

在做一個Web JS SDK(A)時,內(nèi)部會用到另一個Web JS SDK(B)的方法。(文中后續(xù)用A/B代替兩者)

B通常會提供Script和NPM包兩種使用方式

使用npm pkg的缺點(diǎn)

  • 增加包體積
  • 如果這個SDK被Web應(yīng)用已經(jīng)引入過頁面,那么理論上可直接使用,不必要再整一個

如果SDK B包含script引入的方式,目標(biāo)頁面也存在可能會引入B的情況,那么優(yōu)先考慮使用Script引入依賴的SDK的情況:例如

  • 目標(biāo)頁面已經(jīng)引入過JQuery(符合SDK A的使用需求),那么SDK A就可以直接使用已經(jīng)存在的$進(jìn)行操作即可,不必再創(chuàng)建jQuery的script
  • 通常頁面都會接入埋點(diǎn)監(jiān)控等基建服務(wù)SDK B,SDK A也需要通過B進(jìn)行數(shù)據(jù)的上報

衍生需求

  • 掛載在window上的函數(shù)不存在時,自動通過script或者polyfill(墊片方法)補(bǔ)全這個方法
  • 調(diào)用方依舊按照SDK B的文檔進(jìn)行使用
  1. window.sdkB(options) 

解決方案

編寫一個通用的工具函數(shù),處理上述的衍生需求

方法定義如下

  1. function patchWindowFun( 
  2.   key: string, 
  3.   value: string | Function
  4.   options?: { 
  5.     afterScriptLoad?: Function 
  6.     beforeAppendScript?: Function 
  7.     alreadyExistCB?: Function 
  8.     async?: boolean 
  9.     defer?: boolean 
  10.   }, 

總共支持傳入3個參數(shù):

  1. key:帶判斷的方法在window上的屬性名
  2. value:不存在時的取值(function 表明直接使用此方法代替,string類型表明方法來源外部加載的js資源)
  3. options:是一些可選的配置項(xiàng),主要用于處理使用過外部js資源加載方法的場景
  • afterScriptLoad:資源加載完成后的回掉
  • beforeAppendScript:資源加載前的回掉
  • alreadyExistCB:方法如果已經(jīng)存在執(zhí)行的回掉
  • async:控制script的async屬性
  • defer:控制script的defer屬性

由于大多數(shù)web sdk都會存在需要調(diào)用特定函數(shù)或者方法進(jìn)行初始化的情況,固提供了afterScriptLoad,beforeAppendScript,alreadyExistCB三個鉤子函數(shù)處理不同時機(jī)初始化的情況

方法實(shí)現(xiàn)

如果目標(biāo)屬性存在則直接執(zhí)行相應(yīng)的回調(diào),不做進(jìn)一步處理

  1. if (window[key]) { 
  2.   alreadyExistCB && alreadyExistCB() 
  3.   console.log(key'already exist'
  4.   return 

目標(biāo)屬性不存在,傳入的方法存在時直接進(jìn)行賦值

  1. // 函數(shù)直接賦值 
  2. if (typeof value === 'function') { 
  3.   window[key] = value 
  4.   return 

剩余邏輯則是處理方法從外部js資源加載的情況

由于加載script大部分情況是異步的,業(yè)務(wù)代碼中可能已經(jīng)調(diào)用了相關(guān)方法,為此臨時創(chuàng)建一個方法收集傳入的參數(shù)

  1. let params = [] 
  2. window[key] = function () { 
  3.   params.push(arguments) 

下面的邏輯就是處理script加載的邏輯

在js資源加載完成后通過apply配合forEach將提前調(diào)用方法產(chǎn)生的參數(shù)重新正確的執(zhí)行一次

  1. const script = document.createElement('script'
  2. script.src = value 
  3. script.async = !!defer 
  4. script.defer = !!async 
  5. script.onload = function () { 
  6.   afterScriptLoad && afterScriptLoad() 
  7.   // 處理原來沒處理的 
  8.   params.forEach(param => { 
  9.     window[key].apply(this, param) 
  10.   }) 
  11. beforeAppendScript && beforeAppendScript() 
  12. document.body.append(script) 

完整源碼如下

  1. function patchWindowFun( 
  2.   key: string, 
  3.   value: string | Function
  4.   options?: { 
  5.     afterScriptLoad?: Function 
  6.     beforeAppendScript?: Function 
  7.     alreadyExistCB?: Function 
  8.     async?: boolean 
  9.     defer?: boolean 
  10.   }, 
  11. ) { 
  12.   // 存在不處理 
  13.   const { alreadyExistCB, afterScriptLoad, beforeAppendScript, defer, async } = options || {} 
  14.  
  15.   if (window[key]) { 
  16.     alreadyExistCB && alreadyExistCB() 
  17.     console.log(key'already exist'
  18.     return 
  19.   } 
  20.  
  21.   // 函數(shù)直接賦值 
  22.   if (typeof value === 'function') { 
  23.     window[key] = value 
  24.     return 
  25.   } 
  26.  
  27.   // script url 
  28.   if (typeof value === 'string') { 
  29.     let params = [] 
  30.     window[key] = function () { 
  31.       params.push(arguments) 
  32.     } 
  33.  
  34.     const script = document.createElement('script'
  35.     script.src = value 
  36.     script.async = !!defer 
  37.     script.defer = !!async 
  38.     script.onload = function () { 
  39.       afterScriptLoad && afterScriptLoad() 
  40.       // 處理原來沒處理的 
  41.       params.forEach(param => { 
  42.         window[key].apply(this, param) 
  43.       }) 
  44.     } 
  45.     beforeAppendScript && beforeAppendScript() 
  46.     document.body.append(script) 
  47.   } 

小結(jié)

目前的方法實(shí)現(xiàn)僅適用于,調(diào)用的方法相對獨(dú)立不影響正常的交互

 

如果業(yè)務(wù)代碼依賴方法的返回值,那么異步通過script加載的方法方式將不太適用

 

責(zé)任編輯:武曉燕 來源: 粥里有勺糖
相關(guān)推薦

2019-12-31 09:11:01

后臺Android系統(tǒng)

2009-09-12 09:34:18

Windows 7中國售價

2018-07-19 06:14:09

2021-01-25 07:21:24

GitHub 開源代碼下載

2023-09-12 08:02:13

viewport斷點(diǎn)

2018-07-03 14:20:10

數(shù)據(jù)庫恢復(fù)備份

2018-06-25 15:08:34

打印機(jī)處理打印

2024-12-13 08:25:59

DML操作SQL

2020-11-03 10:23:22

云計算容器技術(shù)

2024-07-22 08:03:55

2017-12-07 14:57:13

404互聯(lián)網(wǎng)錯誤代碼

2017-12-26 08:25:57

硬盤數(shù)據(jù)丟失

2012-05-16 11:35:16

SQL Server拒絕訪問

2021-03-08 15:28:18

滴滴網(wǎng)約車大數(shù)據(jù)

2015-10-20 10:30:59

創(chuàng)業(yè)時機(jī)

2011-07-13 10:01:16

域控制器

2018-07-03 10:09:18

閃存

2010-01-05 13:52:02

2023-10-13 09:46:48

2018-01-18 09:43:46

調(diào)研 計算機(jī) 薪資
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號