0

I want my javascript/jquery application to stop executing all animations, and only continue executing when a loading .gif is shown.

I did manage to show the loading .gif while other animations where going on, but I really need it to already show before anything else is animated.

So I fabricated a method that waits for the callback to be executed, but it doesn't work as expected.

var Shown = false;
function ShowLoadingGif() {
    $("#loading").show("fast", function() {
        Shown = true;   
    });
    while(!Shown) {
        //wait for callback to be executed
    }
    Shown = false;
}

See this JFiddle example. I would not only like to know how to properly go about solving this problem; I would also appreciate any input as to why it doesn't work as I expect it to.

Thanks in advance!

Rory McCrossan
  • 331,213
  • 40
  • 305
  • 339
Klaassiek
  • 2,795
  • 1
  • 23
  • 41
  • 2
    because javascript follows a single thread execution pattern... that means your while loop causes the application thread to stop executing any other code including the `show` animation... that means the `shown` variable never becomes `true` thus your while condition is never exited – Arun P Johny May 08 '14 at 12:46
  • maybe this helps: http://stackoverflow.com/questions/6923647/how-to-attach-callback-to-jquery-effect-on-dialog-show – caramba May 08 '14 at 12:47
  • 3
    the only way to handle this kind of async methods is to use callbacks – Arun P Johny May 08 '14 at 12:48
  • 1
    `while(!Shown)` will crash your browser. – Jonathan May 08 '14 at 12:49
  • If you're saying that the animations are already running, you want to pause them, show a gif, and then let them continue then you're looking at a big issue - much bigger than simply moving some code into a callback function, which is what the question sounds like – Reinstate Monica Cellio May 08 '14 at 12:54

2 Answers2

1

You can use something like this, using the jQuery Deferred Object ( see Docs )

var Shown = false;
function ShowLoadingGif() {
    var $promise = $.Deferred();
    $("#loading").show("fast", function() {
        $promise.resolve("Im done");
    });
    $promise.done(function(data) {
         // data === "Im done"
    });
}

I have updated your Fiddle that now alerts when the stuff has finished as you would expect

Fiddle (http://jsfiddle.net/k5Wan/3/)

Also I have updated the code quality

var $promise = $.Deferred();

$promise.done(function() {
    alert("Done...");
});

$(function() {
    $("button").on("click", function() {
        $("#loading").show("slow", function() {
            $promise.resolve();
        });
    });
});
Luke
  • 8,235
  • 3
  • 22
  • 36
0

You can shorten all that:

$('#loading').show('fast', function(){
  console.log('Im loaded');
}).promise().done(function(){
  console.log('great loading with you!');
});

DEMO

Alex Shilman
  • 1,547
  • 1
  • 11
  • 15
  • Thank, but I cannot get this to work. Could you have a look at this: http://jsbin.com/nuvokuxe/1/edit and tell me how to make sure the "loading gif should have been shown by now" message can be delayed intil after the "great" message? – Klaassiek May 08 '14 at 14:13
  • Take a look: http://jsbin.com/nuvokuxe/2/edit . You have to put everything that needs to be delayed into the callback function in the done(function(){...}) – Alex Shilman May 08 '14 at 14:38
  • @user2288476 if you find my answer useful, please dont forget to mark it as useful. If you have any other questions let me know. – Alex Shilman May 08 '14 at 14:52
  • well, thanks, but putting everything inside the done-function is exactly not what I want. To be more precise about what I want: I need to call the ShowLoadingGif() from numerous points in my javascript and the rest of the javascript code should wait for the picture to show. The rest of the javascript can be anything from one line to one hundred lines depending on where I call the ShowLoadginGif()-function. So I really need to wait for the picture to show and only then exit the function. – Klaassiek May 08 '14 at 15:22