如何在使用Appcelerator在Android中进入下一个循环之前等待函数完成

时间:2015-04-30 13:56:25

标签: javascript android titanium appcelerator

所以我有一个从API预加载图形的应用程序。

我首先从我的板载数据库中获取所需的所有数据,然后循环访问它并将用户发送到下载图像,调整大小等功能。

在iOS上看起来效果很好,但是在Android上却不断下滑。

我正在寻找一种更优雅的方式来做这件事,这不会让应用程序崩溃。

有没有办法可以在我的循环(来自getMarker()函数)之前等待getMapMarkers()函数完成另一个请求?

以下是我的应用程序部分的代码段。函数getMarker()执行图像处理和调整大小。

function getMarker(url, filename) {

    var mapMarker = Ti.Filesystem.getFile(Ti.Filesystem.applicationDataDirectory, 'map_marker_icons', filename);

    // now we need to download the map marker and save it into our device 
    var getMarker = Titanium.Network.createHTTPClient({
        timeout: 30000
    });

    getMarker.onload = function() {

        // if the file loads, then write to the filesystem
        if (getMarker.status == 200) {

                var image = this.responseData;
                // resize to 75 pixel marker
                var resizedImage = image.imageAsResized(75, 75);
                mapMarker.write(resizedImage);

                //I ALWAYS NULL ANY PROXIES CREATED SO THAT IT CAN BE RELEASED
                image = null;
                resizedImage = null;
                mapMarker = null;


        } else {
            Ti.API.info("Image not loaded");
        }


        //getMarker = null;


    };

    getMarker.onerror = function(e) {
        Ti.API.info('XHR Error ' + e.error);
        //alert('markers data error');
    };

    getMarker.ondatastream = function(e) {


        if (e.progress == 1) {
            Ti.API.info(filename + ' Download Complete');

        }
    };

    // open the client
    getMarker.open('GET', url);

    // send the data
    getMarker.send();

}

function getMapMarkers() {
    // get the species list back
    var db = Ti.Database.open('myDB');
    var getSpeciesImages = db.execute('SELECT speciesiconfilename, speciesmapiconurl FROM species where speciesiconfilename <> ""');

    // YOU ONLY NEED TO DO THIS ONCE SO DO IT OUTSIDE THE LOOP
    var imgDir = Ti.Filesystem.getFile(Ti.Filesystem.applicationDataDirectory, 'map_marker_icons');

    // if the directory doesn't exist, then we need to create it
    if (!imgDir.exists()) {
        // If the directory doesn't exist, make it
        imgDir.createDirectory();
    };

    // start the loop
    while (getSpeciesImages.isValidRow()) {
        var filename = getSpeciesImages.fieldByName('speciesiconfilename');
        var url = getSpeciesImages.fieldByName('speciesmapiconurl');

        getMarker(url, filename);

        getSpeciesImages.next();

    } // end the loop

    getSpeciesImages.close();


    // close the database
    db.close();

    // get the exhibit markers next
    getExhibitMapMarkers();
};

任何人都可以提供帮助吗?它让我发疯了!

西蒙

1 个答案:

答案 0 :(得分:1)

它比钛有更多的问题。我更喜欢使用Q库(https://github.com/kriskowal/q)来做这些事情。

function getMarker(url, filename) {
    return function() {
        var defered = Q.defer();

        ...
        var xhr = Titanium.Network.createHTTPClient({
            timeout: 30000
        });

        xhr.onload = function() {
            ...
            defered.resolve();
        };

        xhr.onerror = function(e) {
            ...
            defered.resolve(); // or defered.reject() if you want stop after first error
        }
        ...
        xhr.open('GET', url);
        xhr.send();

        return defered.promise;
    };
}

function getMapMarkers() {
    ...
    var imageRequests = [];

    while(getSpeciesImages.isValidRow()) {
        ...
        imageRequests.push(getMarker(url, filename));
        getSpeciesImages.next();
    }

    imageRequests.reduce(Q.when, Q(true))
    .then(function() {
        Ti.API.info('all loaded');
    });
    ...
};

并且不要将http客户端变量命名为getMarker()函数!