0

次のコードを検討してください。

function func() {
    var totalWidths = 0;
    for( var i = 0, count = arr.length; i < count; i++ ) {
        var image = arr[i];

        insertElemInDOM(image);

        preloadImage(image,function(){
            var w = image.width();
            totalWidths += w;
        });

    }
    // do something with the variable "totalWidths"
    doSomething(totalWidths)
}

ここに2つの問題があります。画像は常に同じになり(最初の問題)、無名関数で解決できます。

    for(...) {
        (function(image) {
            preload(image,function() {
                // now image is the correct one
            });
        })(image);
    }

しかし、後でdoSomething(totalWidths)で使用するために、totalWidths変数を管理するにはどうすればよいですか?前のコードは、totalWidthsの値が0になります。ありがとう!

4

1 に答える 1

2

ループ全体をタイムアウトすることができdoSomethingます。これは、非常に多くのタイムアウトを設定するよりもはるかにパフォーマンスが高くなります。

setTimeout(function() {
    var inc = 0;
    for (var i = 0; i < count; i++) {
        var w = arr[i].width();
        inc++;
    }
    doSomething(inc);
}, 1000);

ただし、実際に必要と思われるのは、ネストされたタイムアウトです。つまり、各反復ステップで1を待機し、すべてが終了した後に何かを実行します。

var inc = 0, count;
function asyncLoop(i, callback) {
    if (i < count) {
        var w = arr[i].width();
        inc++;
        setTimeout(function() {
            asyncLoop(i+1, callback);
        }, 1000);
    } else {
        callback();
    }
}
asyncLoop(0, function() {
    doSomething(inc);
});

OK、これで解決策が必要なことがわかったので、各ロードイベントの後に、すべてのイメージがロードされているかどうかを確認します。

var totalWidths = 0,
    count = arr.length,
    loaded = 0;
for (var i = 0; i < count; i++) 
    (function (image) {
        insertElemInDOM(image);
        preload(image, function() {
            totalWidths += image.width();
            // counter:
            loaded++;
            if (loaded == count-1) // the expected value
                doSomething(totalWidths); // call back
        });
    })(arr[i]);
于 2013-01-10T17:44:36.063 に答える