0

インターネットから3つの画像ファイルをダウンロードし、それらの読み込みにかかった時間を平均して、スピードテストを実装しようとしています。なんらかの理由でエラーが発生した場合は、その画像の読み込みをスキップして次の画像に進みます。最後の画像でエラーが発生した場合は、その時点での平均速度を計算して、発信者に戻ります。

現在、エラーが発生すると(画像のURLを意図的に変更して存在しないようにしました)、それ以上進むことはありません。.onerror関数からtrueを返そうとしましたが、うまくいきませんでした。助言がありますか?

     var images = [{
            "url": 'http://<removed>250k.jpg?n=' + Math.random(),
            "size": 256000
        }, {
            "url": 'http://<removed>500k.jpg?n=' + Math.random(),
            "size": 512000
        }, {
            "url": '<removed>1000k.jpg?n=' + Math.random(),
            "size": 1024000
        }
    ];


function calculateBandwidth() {
    var results = [];
    for (var i = 0; i < images.length; i++) {
        var startTime, endTime;
        var downloadSize = images[i].size;
        var download = new Image();
        download.onload = function () {
            endTime = (new Date()).getTime();

            var duration = (endTime - startTime) / 1000;
            var bitsLoaded = downloadSize * 8;

            var speedBps = (bitsLoaded / duration).toFixed(2);
            var speedKbps = (speedBps / 1024).toFixed(2);
            var speedMbps = (speedKbps / 1024).toFixed(2);

            results.push(speedMbps);

            //Calculate the average speed
            if (results.length == 3) {
                var avg = (parseFloat(results[0]) + parseFloat(results[1]) + parseFloat(results[2])).toFixed(2);
                return avg;
            }
        }
        download.onerror = function (e) {
            console.log("Failed to load image!");
            return true;
        };
        startTime = (new Date()).getTime();
        download.src = images[i].url;
    }
}
4

1 に答える 1

0

あなたがしていないのは、各イベントが発生するたびにプロセスを制御することだと思います。それぞれonerroronloadプロセスが停止したことを通知しますが、それ自体を終了する必要はありません。1つの画像を初期化しますが、読み込まれません。注意してください。それ以外の場合は続行してください。

問題は、あなたも最後に同じことをするということonloadです。つまり、測定を行ってから次の測定に進むか、それ以上ない場合は、クリーンアップしてレポートするスクリプトなどを実行します。

例えば:

var site = 'http://upload.wikimedia.org/',
    imgs = [
    'wikipedia/commons/6/6e/Brandenburger_Tor_2004.jpg',
    'wikipedia/commons/a/ad/Cegonha_alsaciana.jpg',
    'wikipe/Cegonha_alsaciana.jpg',
    'wikipedia/commons/d/da/CrayonLogs.jpg',
    'wikipedia/commons/1/17/Bobbahn_ep.jpg',
    'wikipedia/commons/9/90/DS_Citro%C3%ABn.jpg',
    'wikipedia/commons/f/f0/DeutzFahr_Ladewagen_K_7.39.jpg',
    'wikipedia/commons/c/c7/DenglerSW-Peach-faced-Lovebird-20051026-1280x960.jpg',
    'wikipedia/commons/4/4d/FA-18F_Breaking_SoundBarrier.jpg'
];

私の画像の配列。ヒント、wikipe/Cegonha_alsaciana.jpgロードされません。注意してください、これらは大きくてロードが遅いので、キャッシュバスターを使用してそれらを起動し続けますonload

getimg();

フィドルでは、これはすべてwindow.onloadイベントハンドラー内にあるため、呼び出されると、プロセスが初期化されます。セットアップフェーズ自体はありません。そうでない場合は、またはと呼んでいた可能性がありinit()ますsetup()

function getimg() {
    var img = document.createElement('img'),
        path = imgs.shift();

    if (path) {
        img.onload = loaded;
        img.onerror = notloaded;
        img.src = site + path + '?cach=bust' + Math.floor(Math.random() * 9999);

        console.log('Loading ', img.src);

        document.body.appendChild(img);
    } else {
        console.log('Finished loading images.');
    }

    function loaded(e) {
        console.log('Loaded ', e.target.src);
        next();
    }

    function notloaded(e) {
        console.log('Not loaded ', e.target.src);
        next();
    }

    function next() {
        console.log(imgs.length, ' imgs left to load.');
        getimg();
    }
}

http://jsfiddle.net/userdude/vfTfP/

これは、タイミングメカニズムが組み込まれていなくても、実行しようとしていることを実行します。必要に応じてステップを制御できるように、物事をステップ、アクション、イベントに分割できます。基本的に、スクリプトの実行方法はそれほど変わりません。

于 2013-03-27T00:59:52.467 に答える