itsource

getScript를 동시에 사용

mycopycode 2023. 8. 5. 10:08
반응형

getScript를 동시에 사용

저는 getScript를 상당히 광범위하게 사용해야 하는 엔진을 작성하고 있습니다.사용하기 쉽도록 자체 기능으로 밀어 넣었지만, 이제 기능 자체가 동기화되는지 확인해야 합니다.안타깝게도 계속 진행하기 전에 로드되는 스크립트가 실제로 로드될 때까지 getScript를 기다리게 할 수 없습니다.통화하기 전에 jQuery의 ajax 비동기 속성을 false로 설정해보기도 했습니다.저는 jQuery의 when/done 프로토콜을 사용할 생각인데, 함수 내부에 배치하고 함수 자체를 동기화하는 논리에 머리를 감을 수가 없습니다.어떤 도움이라도 주시면 대단히 감사하겠습니다!

function loadScript(script){
//Unrelated stuff here!!!
$.when(
$.getScript(script,function(){
    //Unrelated stuff here!!!
})).done(function(){
    //Wait until done, then finish function
});
}

루프 코드(요청별):

for (var i in divlist){
        switch($("#"+divlist[i]).css({"background-color"})){
            case #FFF:
            loadScript(scriptlist[0],divlist[i]);
            break;
        case #000:
            loadScript(scriptlist[2],divlist[i]);
            break;
        case #333:
            loadScript(scriptlist[3],divlist[i]);
            break;
        case #777:
            loadScript(scriptlist[4],divlist[i]);
            break;
    }
}

이것은 저에게 효과가 있었고, 당신에게 도움이 될 수도 있습니다.

$.ajax({
    async: false,
    url: "jui/js/jquery-ui-1.8.20.min.js",
    dataType: "script"
});

기본적으로, 저는 단지 속기 표기법을 생략하고 다음에 추가했습니다.async: false

제가 말했듯이, Ajax 호출을 약속 객체와 연결하는 것은 비교적 쉽습니다.이제 스크립트를 차례로 로드해야 하는 이유를 알 수 없지만, 이유가 있을 것입니다.

내가 먼저 제거할 것이지만,switch다른 인수를 사용하여 동일한 함수만 호출하는 경우 문.예를 들어 모든 스크립트 URL을 맵에 넣을 수 있습니다.

var scripts = {
    '#FFF': '...',
    '#000': '...'
    // etc.
};

전달된 [계속]콜백에서 다른 약속을 반환하는 것만으로 약속을 연결할 수 있습니다. 약속이나 연기된 개체로 시작하기만 하면 됩니다.

var deferred = new $.Deferred();
var promise = deferred.promise();

for (var i in divlist) {
    // we need an immediately invoked function expression to capture
    // the current value of the iteration 
    (function($element) {
        // chaining the promises, 
        // by assigning the new promise to the variable
        // and returning a promise from the callback
        promise = promise.then(function() {
            return loadScript(
                scripts[$element.css("background-color")], 
                $element
            );
        });
    }($('#' + divlist[i])));
}

promise.done(function() {
    // optional: Do something after all scripts have been loaded
});

// Resolve the deferred object and trigger the callbacks
deferred.resolve();

loadScript당신은 단순히 반환된 약속을 반환합니다.$.getScript또는 가 반환한 것..done:

function loadScript(script_url, $element){
    // Unrelated stuff here!!!

    return $.getScript(script_url).done(function(){
        //  Unrelated stuff here
        // do something with $element after the script loaded.
    });
}

모든 스크립트는 루프에서 액세스하는 순서대로 호출됩니다.참고: 만약divlist배열입니다. 당신은 정말로 일반을 사용해야 합니다.for루프 대신 루프for...in고리.

알고 계십니까?$.getScript 스크립트가 로드된 후 동기적으로 호출되는 콜백 함수를 수락합니까?

예:

$.getScript(url,function(){
//do after loading script
});

저는 두 가지 해결책이 더 있습니다. 하나는 순수jsone이고 하나는 다중 jsload용입니다.

이 방법을 사용하여 지연된 개체로 배열을 만들고 "적용"할 때 $.를 사용합니다.

var scripts = [
    'src/script1.js',
    'src/script2.js'
];

var queue = scripts.map(function(script) {
    return $.getScript(script);
});

$.when.apply(null, queue).done(function() {
    // Wait until done, then finish function
});
var getScript = function(url) {
    var s = document.createElement('script');
    s.async = true;
    s.src = url;
    var to = document.getElementsByTagName('script')[0];
    to.parentNode.insertBefore(s, to);
};

@펠릭스 클링의 대답은 훌륭한 시작이었습니다.그런데 전체적으로 첨부된 부분에 약간의 문제가 있는 것을 발견했습니다..done()말에.getScripts()결과를 반환했습니다(기능화).당신은 사슬에 묶인 마지막 약속이 필요합니다..getScript()반복을 반복합니다.여기 그의 솔루션의 수정된 버전이 있습니다(BTW 감사합니다).

플러그인:

(function ($) {
    var fetched = new function () {
            this.scripts = [];
            this.set = [];

            this.exists = function (url) {
                var exists = false;

                $.each(this.set, function (index, value) {
                    if ((url || '') === value) {
                        exists = true;

                        return false;
                    }
                });

                return exists;
            };

            this.buildScriptList = function () {
                var that = this;

                that.set = [];

                $('script').each(function () {
                    var src = $(this).attr('src') || false;

                    if (src) {
                        that.set.push(src);
                    }
                });

                $.merge(this.set, this.scripts);

                return this;
            };
        },
        getScript = $.getScript;

    $.getScript = function () {
        var url = arguments[0] || '';

        if (fetched.buildScriptList().exists(url)) {
            return $.Deferred().resolve();
        }

        return getScript
            .apply($, arguments)
            .done(function () {
                fetched.scripts.push(url);
            });
    };

    $.extend({
        getScripts: function (urls, cache) {
            if (typeof urls === 'undefined') {
                throw new Error('Invalid URL(s) given.');
            }

            var deferred = $.Deferred(),
                promise = deferred.promise(),
                last = $.Deferred().resolve();

            if (!$.isArray(urls)) {
                urls = [urls];
            }

            $.each(urls, function (index) {
                promise = promise.then(function () {
                    last = $.getScript(urls[index]);

                    return last;
                });
            });

            if (Boolean(cache || false) && !Boolean($.ajaxSetup().cache || false)) {
                $.ajaxSetup({cache: true});

                promise.done(function () {
                    $.ajaxSetup({cache: false});
                });
            }

            deferred.resolve();

            return last;
        }
    });
})($);

페치된 할 수 . (를 줄이기 했습니다. - 가 기잠무수있다습할시니가져다능은니습구위했현줄온기해이통를재인화중복적잠▁(▁i▁you(다습▁hijacked니다▁-가있니▁whichi▁fet▁reduce져▁redundant▁the습▁calls▁why▁is▁toedched▁function▁it▁ignore했) 그래서 납치했습니다..getScript()및에 있는지 합니다).last는 내에설니다됩정 되어 있습니다..getScripts()으로 객체로 되어 외부 URL을 첨부합니다..done()부르짖다그렇지 않으면 체인에서 마지막 약속 개체가 할당됩니다..getScript()모든 것이 기능 외부에서 동기화된 상태로 유지되도록 합니다.

처음에 생성된 지연 개체를 다시 호출자에게 반환하기 전에 해결하는 경우(이는 jQuery의 공식 문서에 따라 수행해야 하는 작업)에는 해당 개체가 반환되지 않습니다.

예:

function loadStuff(data) {
    var version = {
        'accounting': '1.2.3',
        'vue': '1.2.3',
        'vueChart': '1.2.3'
    };

    $.getScripts([
        'https://cdnjs.cloudflare.com/ajax/libs/accounting.js/' + version.accounting + '/accounting.min.js',
        'https://cdnjs.cloudflare.com/ajax/libs/vue/' + version.vue + '/vue.min.js',
        'https://cdnjs.cloudflare.com/ajax/libs/vue-chartjs/' + version.vueChart + '/vue-chartjs.min.js'
    ], true)
        .done(function () {
            // do stuff
        })
        .fail(function () {
            throw new Error('There was a problem loading dependencies.');
        });
}

스크립트 노드를 생성하고 src 속성을 로드할 JS로 설정한 다음 헤드에 추가하기만 하면 됩니다.

var myScript = document.createElement('script');
myScript.src = "thesource.js";
document.head.appendChild(myScript);

이것이 내가 하는 일입니다.

function loadJsFile(filename) {
    $.ajaxSetup({
        cache: true
    });

    var dloadJs = new $.Deferred();
    $.when(dloadJs).done(function () {
        $.ajaxSetup({
            cache: false
        });
    });

    dloadJs.resolve(
         $.getScript(filename, function () { })
    );
}

언급URL : https://stackoverflow.com/questions/14783046/using-getscript-synchronously

반응형