By Noxxxx from https://interview.noxxxx.com/?post_type=post&p=69 上山打老虎
欢迎分享与聚合,尊重版权,可以联系授权
要求:
- 加载完成后可以执行方法
- 不能重复加载
- 支持 CSS 文件和 JS 文件加载
思路:
- 使用闭包解决重复加载问题
- 使用 Promise 解决执行成功后的回调问题
具体实现:
迷惑的地方:重复 import 导入函数,闭包还是否有效?实际上重复引入某个函数的时候,该方法是最开始函数执行后的 function,因此闭包会一直存在,多个文件内引入也会保留同一个闭包。
function load() {
// 重复引入只会执行一次,因此闭包有效
const loaded = new Map()
return function (url: string) {
if (loaded.has(url)) return Promise.resolve(true)
return new Promise((resolve, reject) => {
if (url.includes('css')) {
const style = document.createElement('link')
style.href = url
style.rel = 'stylesheet'
style.type = 'text/css'
style.onload = () => {
resolve(true)
}
style.onerror = (e) => {
reject(e)
}
document.head.appendChild(style);
} else if (url.includes('.js')) {
loaded.set(url, true)
const script = document.createElement('script');
script.src = url
script.onload = function () {
resolve(true)
}
script.onerror = function (e) {
reject(e)
}
document.body.appendChild(script);
} else {
throw new Error('url 类型不符合 css 或 js')
}
})
}
}
export const loadAsset = load()