zoukankan      html  css  js  c++  java
  • 如何优雅的实现js资源的按序加载


    theme: fancy

    在实际的开发过程中,我们有时候会遇到动态加载静态资源的需要,这当然是一个很简单的需求,但是如何做到更优雅的实现呢?

    参考优秀的vue-ueditor-wrap

    首先,我们可以采用回调函数的方法实现

    function loadScript(link, cb){
        if(typeof cb !== 'function'){
            cb = function(){}
        }
        const script = document.createElement('script');
        srcipt.src = link;
        script.onload = cb;
        script.onerror = reject;
        document.getElementsByTagName('head')[0].appendChild(script);
    }
    
    loadScript('XXX.js', loadScript('X1.js', /*...*/ ))
    

    上面的方法,如果依赖的js比较多,写出来的代码就会很丑。

    通过Promise来实现,会让我们的代码看起来更加优雅

    var cache = {}
    function loadScript(link){
        if(cache[link]) return Promise.resolve()
        return new Promise((resolve, reject)=>{
            function success(){
                cache[link] = true
                resolve()
            }
            function fail(){
                reject(link)
            }
            const script = document.createElement('script');
            srcipt.src = link;
            script.onload = success;
            script.onerror = fail;
            document.getElementsByTagName('head')[0].appendChild(script);
        })
    }
    

    实现加载资源的函数

    
    
    // 依次加载依赖的 JS 文件
    // 通过reduce将要加载的js通过promise链串联起来
    // 动态创建 script 是先加载完的先执行,所以不可以一次性创建所有资源的引入脚本
    // 根据promise的异常传透原理, 如果有一个加载错误,后面的js就不再加载,并将错误的js连接直接抛出
    function asyncSeries(funs){
         return funs.reduce((promise, fun) => promise.then(fun), Promise.resolve());
    }
    function loadStaticSource(links:[]){
        return new Promise((resolve, reject)=>{
            asyncSeries(jsLinks.map((link) => () => loadScript(link)))
            .then(resolve)
            .catch(reject);
        })
    }
    
    

    测试一下,效果不错!

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
    </head>
    
    <body>
        <script>
            var cache = {}
            function loadScript(link) {
                if (cache[link]) return Promise.resolve()
                return new Promise((resolve, reject) => {
                    function success() {
                        cache[link] = true
                        resolve()
                    }
                    function fail() {
                        reject(link)
                    }
                    const script = document.createElement('script');
                    script.src = link;
                    script.onload = success;
                    script.onerror = fail;
                    document.getElementsByTagName('head')[0].appendChild(script);
                })
            }
            function asyncSeries(funs) {
                return funs.reduce((promise, fun) => promise.then(fun), Promise.resolve());
            }
            function loadStaticSource(links) {
                return new Promise((resolve, reject) => {
                    let p = asyncSeries(links.map((link) => () => loadScript(link)))
                    
                    p.then(resolve)
                        .catch(reject);
                })
            }
            const links = ['https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js', 'yy.js', 'https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js'];
    
            const links1 = ['https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js', 'https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js']
            
            loadStaticSource(links).then(() => {
                console.log("资源加载完成")
            }, (link) => {
                console.log(link + "资源加载错误")
            })
    
            loadStaticSource(links1).then(() => {
                console.log("资源加载完成")
            }, (link) => {
                console.log(link + "资源加载错误")
            })
        </script>
    </body>
    
    </html>
    
  • 相关阅读:
    Hive-0.12.0 配置Mysql的Metasotre
    cdecl、stdcall、fastcall、thiscall函数调用约定区别 (转)
    汇编函数 哪些寄存器在使用时需要保护和恢复现场
    如何用C++ 写Python模块扩展(二)
    如何用C++ 写Python模块扩展(一)
    python装饰器装饰原理探秘
    Linux 命令
    iOS为所需要的视图添加模糊效果--UIVisualEffectView
    UIAlertView ----警告视图
    Virtual Box 下Ubuntu桥接网络设置
  • 原文地址:https://www.cnblogs.com/recode-hyh/p/15207901.html
Copyright © 2011-2022 走看看