最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Titanium mvc - call function and wait for result - Stack Overflow

programmeradmin1浏览0评论

I am currently in the process of making my first Titanium iPhone app.

In a model I got:

(function() {   
    main.model = {};

    main.model.getAlbums = function(_args) {

        var loader = Titanium.Network.createHTTPClient();  
        loader.open("GET", ""); 

        // Runs the function when the data is ready for us to process 
        loader.onload = function() { 
            // Evaluate the JSON  
            var albums = eval('('+this.responseText+')');  
            //alert(albums.length);
            return albums;
        }; 

        // Send the HTTP request  
        loader.send();  

    };

})();

and I call this function in a view like:

(function() {

    main.ui.createAlbumsWindow = function(_args) {

        var albumsWindow = Titanium.UI.createWindow({  
            title:'Albums',
            backgroundColor:'#000'
        });

        var albums = main.model.getAlbums();

        alert(albums);

        return albumsWindow;
    };
})();

however it seems like the call to the model (which fetches some data using HTTP) doesn't wait for a response. In the view when I do the alert it haven't received the data from the model yet. How do I do this in a best-practice way?

Thanks in advance

I am currently in the process of making my first Titanium iPhone app.

In a model I got:

(function() {   
    main.model = {};

    main.model.getAlbums = function(_args) {

        var loader = Titanium.Network.createHTTPClient();  
        loader.open("GET", "http://someurl.json"); 

        // Runs the function when the data is ready for us to process 
        loader.onload = function() { 
            // Evaluate the JSON  
            var albums = eval('('+this.responseText+')');  
            //alert(albums.length);
            return albums;
        }; 

        // Send the HTTP request  
        loader.send();  

    };

})();

and I call this function in a view like:

(function() {

    main.ui.createAlbumsWindow = function(_args) {

        var albumsWindow = Titanium.UI.createWindow({  
            title:'Albums',
            backgroundColor:'#000'
        });

        var albums = main.model.getAlbums();

        alert(albums);

        return albumsWindow;
    };
})();

however it seems like the call to the model (which fetches some data using HTTP) doesn't wait for a response. In the view when I do the alert it haven't received the data from the model yet. How do I do this in a best-practice way?

Thanks in advance

Share Improve this question asked Dec 11, 2011 at 1:34 user328146user328146
Add a ment  | 

5 Answers 5

Reset to default 6

OK,

Something like this,

function foo(arg1, callback){
     arg1 += 10;
     ....
     ... Your web service code
     ....
     callback(arg1); // you can have your response instead of arg1
}

you will call this function like this,

foo (arg1, function(returnedParameter){
     alert(returnedParameter); // here you will get your response which was returned in   above function using this line .... callback(arg1);
});

so here arg1 is parameter (simple parameter like integer, string etc ... ) and second argument is your call back function.

Cheers.

What you need is Synchronous call to web service, so that it will wait till you get the response from the service.

To achieve this in java script you have to pass callback function as parameter and get the return value in callback function instead of returning value by return statement.

Actually coding style you are using is new for me because i am using different coding style.

But the main thing is you have to use call back function to retrieve value instead of return statement. Try this and if you still face the problem than tell me i will try to give an example.

the callback way like zero explained is nicely explained, but you could also try to get it handled with events.

(function() {

    main.ui.createAlbumsWindow = function(_args) {

        var albumsWindow = Titanium.UI.createWindow({  
            title:'Albums',
            backgroundColor:'#000'
        });

        var status = new object(), // eventlistener
        got_a_valid_result = false;

        // catch result
        status.addEventListener('gotResult',function(e){
          alert(e.result);
          got_a_valid_result = true;
        });           

        // catch error
        status.addEventListener('error',function(e){
          alert("error occured: "+e.errorcode);
          git_a_valid_result = true;
        });

        var albums = main.model.getAlbums(status);

        // wait for result
        while (!got_a_valid_result){};
        return albumsWindow;
    };
})();

and your model may something like

main.model.getAlbums = function(status) {

        var loader = Titanium.Network.createHTTPClient();  
        loader.open("GET", "http://someurl.json"); 

        loader.onload = function() { 
            var albums = eval('('+this.responseText+')');  

            status.fireEvent('gotResult',{result:albums});
            return albums;
        }; 

        loader.onerror = function(e){
            status.fireEvent('error',{errorcode:"an error occured"});
        };

        // Send the HTTP request  
        loader.send();  

    };

Just as a suggestion, try to use JSON.parse instead of eval as there are risks involved with using eval since it runs all javascript code.

I think that the solution The Zero posted is likely better for memory management, but I'm not totally sure. If you do and eventListener, be aware of the following (see https://wiki.appcelerator/display/guides/Managing+Memory+and+Finding+Leaks)

function doSomething(_event) {
    var foo = bar;
}
// adding this event listener causes a memory leak
// as references remain valid as long as the app is running
Ti.App.addEventListener('bad:idea', doSomething);

// you can plug this leak by removing the event listener, for example when the window is closed
thisWindow.addEventListener('close', function() {
// to remove an event listener, you must use the exact same function signature
// as when the listener was added
Ti.App.removeEventListener('bad:idea', doSomething);
});
发布评论

评论列表(0)

  1. 暂无评论