3

I am racking my brain trying to figure out how this is used properly. Most all examples use ajax so maybe this is not even possible.

In my example, I create a function, which fades out an element. I realize that .fadeOut can have a callback but I would like to avoid that just for learning purposes.

I read that I need to return a promise or else the $.when().done() would fire immediately. Even though I have attached a promise, it still fires right away.

Here is my simple code

function hide() {
    return $("#element").fadeOut(250).promise();
}

$.when( hide() ).done(function(){
    alert("Hidden");
});

Are there certain methods that can not be used with $.when() such as .fadeOut()?

Any help in understanding would be awesome.

guest271314
  • 1
  • 15
  • 104
  • 177
VIDesignz
  • 4,703
  • 3
  • 25
  • 37
  • `$.Deferred` would be awesome – Norlihazmey Ghazali Feb 27 '16 at 01:45
  • _"Even though I have attached a promise, it still fires right away."_ Note, the duration at `fadeOut` is only `250ms` at `js` at Question ; tried increasing `duration` of `.fadeOut()` ? What is expected result ? – guest271314 Feb 27 '16 at 01:47
  • @NorlihazmeyGhazali Can you explain a bit? – VIDesignz Feb 27 '16 at 01:56
  • @guest271314 Yes, I have increased to 10000ms and it still fires instantly. The `hide()` function gets triggered by a button press. I am not sure if this is causing an issue somehow. – VIDesignz Feb 27 '16 at 01:56
  • 1
    You only need to use `$.when` if you are passing more than one argument to it. Otherwise, call `.done` directly on that argument. – Felix Kling Feb 27 '16 at 01:57
  • @VIDesignz _"Yes, I have increased to 10000ms and it still fires instantly."_ This should not be the case. Actually, `$.when()` is not necessary when returning `.promise()` ; you should be able to chain `.done()` or `.then()` to `hide` function https://jsfiddle.net/7nodhwgy/ – guest271314 Feb 27 '16 at 01:58
  • Here is a fiddle that is more like my setup https://jsfiddle.net/6mLshe77/7/ – VIDesignz Feb 27 '16 at 02:04

2 Answers2

1

You should rearrange placement of .done() . At https://jsfiddle.net/6mLshe77/7/ hide() function is immediately called, without waiting for click event at $.when( hide() ).done(function(){alert("Hidden");})

var div = $("<div/>").attr({
  id: "element"
});

$("button").on("click", function() {
  $("#wrapper").append(div);
  hide().done(function() {
    alert("Hidden");
  });
})

function hide() {
  return $("#element").fadeOut(1000).promise();
}
div {
  width: 100px;
  height: 100px;
  border: 1px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<div id="wrapper"></div>

<button>
  Click Me
</button>

jsfiddle https://jsfiddle.net/6mLshe77/9/

guest271314
  • 1
  • 15
  • 104
  • 177
  • This makes a lot more sense. I had no idea that hide() was called right off the bat. I assumed $when() was "waiting" for it to be called elsewhere. – VIDesignz Feb 27 '16 at 02:14
  • @VIDesignz `hide()` was called at `$.when()` , without waiting for `click` event at https://jsfiddle.net/6mLshe77/7/ . A `$.Deferred()` object could be created that waited for the deferred to be resolved before calling `.done()` - though not necessary when returning a jQuery `.promise()` object from a function . `$.when()` is an alias for `$.Deferred(beforeStart)` . See also http://api.jquery.com/jQuery.when/ , http://api.jquery.com/jQuery.Deferred/ , http://api.jquery.com/promise/ – guest271314 Feb 27 '16 at 02:20
  • @VIDesignz: `()` after a function reference (`hide` resolves to a function) always calls the function. – Felix Kling Feb 27 '16 at 02:32
0

I'm not an expert on promises but it seems like you don't need to return a promise.

https://api.jquery.com/promise/

https://jsfiddle.net/6mLshe77/

function hide() {
    return $("#element").fadeOut(1000);
}

$.when( hide() ).done(function(){
    alert("Hidden");
});
Eric Guan
  • 15,474
  • 8
  • 50
  • 61
  • Ok, maybe I have it all wrong. Does `$.when()` trigger the function `hide()`? – VIDesignz Feb 27 '16 at 01:55
  • Well, calling `hide()` triggers the function, it's just that the return value of `hide()` is a deferred object, which `$.when()` accepts as a parameter. So some jquery magic happens and then you can chain `done` and `fail` methods to the `$.when`. – Eric Guan Feb 27 '16 at 01:58
  • @VIDesignz: *"Does `$.when()` trigger the function `hide()`?"* What do you mean by "trigger"? You are (correctly) passing the *return value* of calling `hide` to `$.when`. `$.when` doesn't do anything with the `hide` function itself. – Felix Kling Feb 27 '16 at 01:59
  • @FelixKling So how is his jsfiddle running the hide function without calling it? – VIDesignz Feb 27 '16 at 02:03
  • By writing `hide()`, the function is called. It just seems weird because it's taking place inside a function parameter. – Eric Guan Feb 27 '16 at 02:05
  • @VIDesignz: I'm not sure what you mean. `hide()` calls the function. – Felix Kling Feb 27 '16 at 02:05
  • @FelixKling What I mean is, the only place that `hide()` is written is inside the `$.when( hide() )`...so that means that it is triggering the function there correct? And if that's the case, no wonder I am having issues. – VIDesignz Feb 27 '16 at 02:07
  • @VIDesignz: **You** are calling `hide`. `$.when` simply receives the return value. Maybe this makes it easier to understand: `var promise = hide(); $.when(promise)`. `$.when` doesn't know anything about `hide`. "It" does not "trigger" it. – Felix Kling Feb 27 '16 at 02:09
  • 1
    @FelixKling I get you now, I assumed that `$.when()` was more of a listener so to speak. Waiting for `hide()` to be called elsewhere. I did not realize that `hide()` ran right then and there. – VIDesignz Feb 27 '16 at 02:12