23

getScript をかなり広範囲に使用する必要があるエンジンを作成しています。使いやすいように独自の関数にプッシュしましたが、関数自体が同期していることを確認する必要があります。残念ながら、getScript がロードするスクリプトのロードが実際に完了するまで待機させてから続行することはできないようです。呼び出しを行う前に、jQuery の ajax asynch プロパティを 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;
    }
}
4

8 に答える 8

11

既に述べたように、Promise オブジェクトを使用して Ajax 呼び出しを連鎖させるのは比較的簡単です。これで、スクリプトを次々にロードする必要がある理由がわかりませんが、それには理由があります。

switch最初に、異なる引数で同じ関数を呼び出すだけの場合は、ステートメントを取り除きます。たとえば、すべてのスクリプト URL をマップに配置できます。

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

.then [docs]に渡されたコールバックから別の promise を返すだけで、promise を連鎖できます。あなたがする必要があるのは、promise または deferred オブジェクトから始めることだけです:

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ください。

于 2013-02-09T02:34:45.850 に答える
3

この方法を試して、遅延オブジェクトで配列を作成し、「適用」で $.when を使用します

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
});
于 2013-02-08T23:46:29.877 に答える
0
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);
};
于 2013-02-09T00:01:11.170 に答える
-1

this is what I do

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

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

    dloadJs.resolve(
         $.getScript(filename, function () { })
    );
}
于 2016-03-30T13:40:38.293 に答える
-1

スクリプト ノードを作成し、その src プロパティをロードする JS に設定してから、ヘッドに追加します。

var myScript = document.createElement('script');
myScript.src = "thesource.js";
document.head.appendChild(myScript);
于 2013-02-08T23:31:59.507 に答える