From 71cfab8d4dd56b24a872d9c8dddf8a98672b36c5 Mon Sep 17 00:00:00 2001 From: roymondchen Date: Thu, 7 Apr 2022 17:38:33 +0800 Subject: [PATCH] =?UTF-8?q?feat(util):=20asyncLoadCss=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E6=8C=87=E5=AE=9Adocument?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/utils/src/index.ts | 52 ++++++++++++++++++++++++++----------- 1 file changed, 37 insertions(+), 15 deletions(-) diff --git a/packages/utils/src/index.ts b/packages/utils/src/index.ts index a6eb9a37..96dcb045 100644 --- a/packages/utils/src/index.ts +++ b/packages/utils/src/index.ts @@ -97,22 +97,44 @@ export const asyncLoadJs = (() => { }; })(); -export const asyncLoadCss = function (url: string) { - return new Promise((resolve, reject) => { - const hasLoaded = globalThis.document.querySelector(`link[href="${url}"]`); - if (hasLoaded) { - resolve(undefined); - return; +export const asyncLoadCss = (() => { + // 正在加载或加载成功的存入此Map中 + const documentMap = new Map(); + + return (url: string, document = globalThis.document) => { + let loaded = documentMap.get(document); + if (!loaded) { + loaded = new Map(); + documentMap.set(document, loaded); } - const node = document.createElement('link'); - node.rel = 'stylesheet'; - node.href = url; - document.getElementsByTagName('head')[0].appendChild(node); - node.onload = resolve; - node.onerror = reject; - }); -}; + // 正在加载或已经加载成功的,直接返回 + if (loaded.get(url)) return loaded.get(url); + + const load = new Promise((resolve, reject) => { + const node = document.createElement('link'); + node.rel = 'stylesheet'; + node.href = url; + document.head.appendChild(node); + node.onload = () => { + resolve(); + }; + node.onerror = () => { + reject(new Error('加载失败')); + }; + setTimeout(() => { + reject(new Error('timeout')); + }, 60 * 1000); + }).catch((err) => { + // 加载失败的,从map中移除,第二次加载时,可以再次执行加载 + loaded.delete(url); + throw err; + }); + + loaded.set(url, load); + return loaded.get(url); + }; +})(); // 驼峰转换横线 export const toLine = (name = '') => name.replace(/\B([A-Z])/g, '-$1').toLowerCase(); @@ -181,4 +203,4 @@ export const getUrlParam = (param: string, url?: string) => { return ''; }; -export const isPop = (node: MNode): boolean => node.type.toLowerCase().endsWith('pop'); +export const isPop = (node: MNode): boolean => Boolean(node.type?.toLowerCase().endsWith('pop'));