【问题标题】:Trigger callback function when two event listeners are fulfilled当两个事件监听器都满足时触发回调函数
【发布时间】:2021-06-10 22:02:56
【问题描述】:

我正在寻找一种优雅的方式来在满足两个加载事件侦听器时调用回调函数。目前我正在使用一个变量,它具有事件侦听器的状态并在间隔中进行检查。这是我描述的情况的一个例子:

function executeExtScript(cb, srcStyle, srcJs) {
    // 01
    let scripts = document.getElementsByTagName('script');
    let scriptExists = false;
    for (let i = scripts.length; i--;) {
        if (scripts[i].src === srcJs) scriptExists = true;
    }
    scriptExists === true ? cb() : loadScript();
    // 02
    function loadScript() {
        let loadFinish = [false, false];
        let head = document.head;
        let style = document.createElement("link");
        style.setAttribute("rel", "stylesheet");
        style.setAttribute("href", srcStyle);
        let script = document.createElement('script');
        script.type = 'text/javascript';
        script.src = srcJs;
        script.onload = () => {loadFinish[0] = true}
        style.onload = () => {loadFinish[1] = true}
        var timer = setInterval(function() {
            if (loadFinish[0] && loadFinish[1]) {
                cb();
                clearInterval(timer);
            }
        }, 100);
        head.appendChild(style);
        head.appendChild(script);
    }
}

有没有更优雅的方法来解决这个问题 - 特别是我想阻止使用设置间隔函数,前提是如果我无法获取其中一个文件,它们可能会运行很长时间

提前致谢

【问题讨论】:

    标签: javascript callback addeventlistener


    【解决方案1】:

    从它们中创建 Promise 并使用 Promise.all

    const promisifyLoad = (element) => new Promise((resolve, reject) => {
        element.addEventListener('load', resolve);
        element.addEventListener('error', reject);
    });
    
    function executeExtScript(cb, srcStyle, srcJs) {
        const scriptExists = [...document.querySelectorAll('script')]
            .some(script => script.src === srcJs);
        if (scriptExists) cb();
        else loadScript();
    
        function loadScript() {
            const { head } = document;
            const style = head.appendChild(document.createElement('link'));
            style.setAttribute("rel", "stylesheet");
            style.setAttribute("href", srcStyle);
            const script = head.appendChild(document.createElement('script'));
            script.src = srcJs;
            Promise.all([
                promisifyLoad(style),
                promisifyLoad(script)
            ])
                .then(cb)
                // .catch(handleErrors);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2015-11-22
      • 2017-01-08
      • 1970-01-01
      • 1970-01-01
      • 2015-10-07
      • 1970-01-01
      • 2020-12-11
      • 2018-01-08
      • 1970-01-01
      相关资源
      最近更新 更多