成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

優雅的處理Window.Fun可能不存在的情況

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

[[425592]]

本文轉載自微信公眾號「粥里有勺糖」,作者粥里有勺糖。轉載本文請聯系粥里有勺糖公眾號。

背景

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

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

使用npm pkg的缺點

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

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

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

衍生需求

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

解決方案

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

方法定義如下

  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個參數:

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

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

方法實現

如果目標屬性存在則直接執行相應的回調,不做進一步處理

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

目標屬性不存在,傳入的方法存在時直接進行賦值

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

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

由于加載script大部分情況是異步的,業務代碼中可能已經調用了相關方法,為此臨時創建一個方法收集傳入的參數

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

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

在js資源加載完成后通過apply配合forEach將提前調用方法產生的參數重新正確的執行一次

  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.   // 函數直接賦值 
  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.   } 

小結

目前的方法實現僅適用于,調用的方法相對獨立不影響正常的交互

 

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

 

責任編輯:武曉燕 來源: 粥里有勺糖
相關推薦

2019-12-31 09:11:01

后臺Android系統

2009-09-12 09:34:18

Windows 7中國售價

2023-09-12 08:02:13

viewport斷點

2018-07-19 06:14:09

2021-01-25 07:21:24

GitHub 開源代碼下載

2018-07-03 14:20:10

數據庫恢復備份

2018-06-25 15:08:34

打印機處理打印

2024-12-13 08:25:59

DML操作SQL

2020-11-03 10:23:22

云計算容器技術

2025-06-19 09:13:10

空指針編程C++17

2024-07-22 08:03:55

2017-12-07 14:57:13

404互聯網錯誤代碼

2017-12-26 08:25:57

硬盤數據丟失

2012-05-16 11:35:16

SQL Server拒絕訪問

2021-03-08 15:28:18

滴滴網約車大數據

2011-07-13 10:01:16

域控制器

2015-10-20 10:30:59

創業時機

2018-07-03 10:09:18

閃存

2023-10-13 09:46:48

2010-01-05 13:52:02

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 黄色毛片在线观看 | 成人免费视频观看 | 天天av综合 | 蜜桃毛片 | 国产日韩欧美精品一区二区三区 | 日本免费一区二区三区 | 天天色影视综合 | www.日韩| 亚洲成人在线视频播放 | 毛片com | 男女网站免费观看 | 激情欧美日韩一区二区 | 99久久精品免费看国产高清 | 99精品网 | xxx.在线观看 | 青青草免费在线视频 | 亚洲二区精品 | 久久久久久国产精品免费免费男同 | 国产91在线精品 | 国产精品视频导航 | 五月天国产 | 一区福利视频 | 谁有毛片 | 羞羞的视频免费观看 | 伊人精品一区二区三区 | 天堂一区二区三区 | 国产精品久久久久aaaa九色 | 欧美一级网站 | 午夜精品久久久久久久久久久久久 | 久久精品免费 | 成人免费视频 | 99免费精品 | jdav视频在线观看免费 | 91精品国产综合久久精品图片 | 国产天堂 | 免费av直接看 | 国家aaa的一级看片 h片在线看 | 精品国产一区二区三区久久久蜜月 | 黄色一级视频 | 久久久久国产精品午夜一区 | 国产精品美女久久久久aⅴ国产馆 |