0

ローカルで利用できる必要があるため、サーバーから画像と pdf ファイルをダウンロードする iOS 用の phonegap アプリがあります。

jQuery を使用して解析し、ダウンロードする必要があるアセットのリストを見つけてから、次のように Phonegap API を使用して FileTransfer を開始します。

// assets is an array that has all pdf and image urls to be downloaded.
assets.map(downloadFile);

function downloadFile(file_url){
    console.log('Downloading file:'+file_url);
    var fileTransfer = new FileTransfer();

    fileTransfer.download(
        file_url,
        get_local_file_path(file_url),
        download_success,
        function(error) {
            stopspin();
            console.log('ERROR downloading: '+ error.source);
            $('#notify-user').html('Downloading failed. <a href="#" onclick="checkLatestIssue()">Try again?</a>')
        }
    );
}

現在、アセットは毎回最大 50 個まで可能です。すべてのファイル転送要求がすぐに送信され、ファイル転送要求の一部がタイムアウトすることがあるため、ローカル アセットを介してレンダリングするにはダウンロードが不完全になることがわかります。

これらすべての問題のダウンロードを、約 5 つの並列ダウンロードでシリアル化する方法はありますか?

4

1 に答える 1

2

アプリケーションで行うことは、ダウンロードする必要があるファイルのグローバル配列を作成し、配列の先頭から最初の要素を取得してダウンロードするコードを開始することです。完了すると、配列内に処理する別の項目があるかどうかを確認し、ある場合はプロセスを最初からやり直します。そうでない場合は、ダウンロードを終了し、アプリケーションが次に行う必要があることを続行します。

ファイルをダウンロードするための空の配列を作成します data_to_process = [];

APIから返された配列フォーム「result」に画像と動画を追加する

// add images to array
$.each( result.images_to_download, function( index, value ) {

    index = index + 1;
    data_to_process.push(
        {
            "type":     "images",
            "filename": value,
            "msg":      "Downloading image "+index+" of "+result.images_to_download.length+"..."
        }
    );
});

// add videos to array
$.each( result.videos_to_download, function( index, value ) {

index = index + 1;
data_to_process.push(
    {
        "type":     "videos",
        "filename": value,
        "msg":      "Downloading video "+index+" of "+result.videos_to_download.length+"..."
    }
);
});

ファイルを処理するコードは次のとおりです。注: ここには、ファイルの内容に基づいて特定のディレクトリにファイルを配置したり、ダウンロードの進行状況のパーセンテージ インジケーターを更新したりするために使用する不要なコードがいくつかあります。

// values for percentages
start_data_length = data_to_process.length;
current_iteration = 0;

// set writing to false
writing = false;

// what we do after each iteration in the data array
var finish_processing = function() {

    // increment iteration count
    current_iteration++;

    // set percent value
    var percent = current_iteration / start_data_length * 100;
    percent = Math.round( percent );
    $('#update_percent').html( percent );

    // remove from array after process
    data_to_process.splice( 0, 1 );

    // set writing back to false so we can start another iteration
    writing = false;
}

// checks if we need to process the next part of the array or not
var check_to_process = function() {

    // console.log('checking if we need to process');

    // if we still have items in the array to process
    if ( data_to_process.length > 0 ) {

        // if we're currently not working on an item
        if ( writing === false ) {

            // process next item in array
            process_download_data();

        } else {

            // not ready yet, wait .5 seconds and check again
            // console.log('busy - waiting to process');
            setTimeout( check_to_process, 500 );
        }

    } else {

        // console.log('nothing left to process');
    }
}

// processes the downloaded data
var process_download_data = function() {

    // set writing to true
    writing = true;

    // current item to process is first item in array
    var current_item = data_to_process[0];

    if ( current_item.msg ) {
        $('#update_item').html(current_item.msg);
    } else {
        $('#update_item').html('Processing update data...');
    }
    // console.log( 'processing this: '+ current_item.filename );

    // if something didn't work right..
    var broke = function(error) {

        // console.log( 'error' );
        // console.log( error );

        // cycle to next item in array
        finish_processing();
    }

    // get the directory of current item's "type"
    var get_directory = function( fileSystem ) { 
        fileSystem.root.getDirectory( current_item.type, {create:true,exclusive:false}, get_file, broke ); 
    } 

    // get the file
    var get_file = function( dirEntry ){

        // if texts
        if ( current_item.type == 'texts' ) {

            dirEntry.getFile( current_item.filename+".txt", {create: true, exclusive: false}, create_text_writer, broke); 

        // if images
        } else if ( current_item.type == 'images' ) {

            var localFileName = current_item.filename.substring(current_item.filename.lastIndexOf('/')+1);

            dirEntry.getFile( localFileName, {create: true, exclusive: false}, create_file_writer, broke);

        // if videos
        } else if ( current_item.type == 'videos' ) {

            var localFileName = current_item.filename.substring(current_item.filename.lastIndexOf('/')+1);

            dirEntry.getFile( localFileName, {create: true, exclusive: false}, create_file_writer, broke);

        // if audios
        } else if ( current_item.type == 'resources' ) {

            var localFileName = current_item.filename.substring(current_item.filename.lastIndexOf('/')+1);

            dirEntry.getFile( localFileName, {create: true, exclusive: false}, create_file_writer, broke);

        // if audios
        } else if ( current_item.type == 'audios' ) {

            var localFileName = current_item.filename.substring(current_item.filename.lastIndexOf('/')+1);

            dirEntry.getFile( localFileName, {create: true, exclusive: false}, create_file_writer, broke);
        }
    } 

    // write to file using filetransfer
    var create_file_writer = function( fileEntry ) {

        if ( current_item.remove === true ) {

            fileEntry.remove( function(entry) {

                // what to do when image is deleted
                finish_processing();

            },broke);

        } else {

            var localPath = fileEntry.fullPath;

            // console.log('Writing to: '+localPath+' from: '+current_item.filename);

            var ft = new FileTransfer();

            ft.download( current_item.filename, localPath, function(entry) {

                // what to do when image is downloaded
                finish_processing();

            },broke);
        }
    }

    // create writer for "texts" type
    var create_text_writer = function( fileEntry ) { 
        fileEntry.createWriter( write_text_file, broke ); 
    } 

    // write to file for "texts" type
    var write_text_file = function( writer ) {

        // write new contents
        writer.write( current_item.data );

        // add item where it needs to be in the document
        if ( current_item.append === true ) {

            $('#'+current_item.marker).nextAll().remove();

            // appending
            // console.log('Appending data to: #'+current_item.id);
            $('#'+current_item.id).append( current_item.data );

        } else {

            // adding
            // console.log('Adding data to: #'+current_item.id);
            $('#'+current_item.id).html( current_item.data );
        }

        // console.log('finished writing: '+current_item.filename);

        finish_processing();
    }

    // request persistent filesystem
    window.requestFileSystem( LocalFileSystem.PERSISTENT, 0, get_directory, broke );

    // check if we need to process the next item yet
    check_to_process();
}

// process data from the update
process_download_data();
于 2012-12-02T01:52:02.283 に答える