Reputation: 33
Here is my code:
function example() {
var post = object.get("owner");
post.fetch({
success: function(post) {
window.titles = post.get("username");
console.log(window.titles);
}
});
console.log(window.titles);
}
The first log works successfully. Outside of the method, the second log prints as undefined. Why?
Upvotes: 0
Views: 55
Reputation: 349
It is helpful to think of asynchronous data as only being defined inside the success callback. While it may not always be true, it's the only time when it's ALWAYS defined. Anytime that you are outside the success callback, the data may not have been retrieved yet and the callback may not have run yet.
This is what your program looks like if you remove the asynchronous call:
function example() {
var post = object.get("owner");
post.fetch();
console.log(window.titles);
}
It is more obvious here that window.titles is undefined.
On a separate thread, elsewhere, once post.fetch() is complete, this will be executed (at some time in the future, who knows when... it could be in 1 ms, it could take 1 day, you really cannot know):
(function(post) {
window.titles = post.get("username");
console.log(window.titles);
})()
Do you see now what the problem is? window.titles has not been set yet. post.fetch()
has been called, but the success callback has not returned yet.
There is no way to do what you're asking, which is, to retrieve data before you've actually retrieved data. Anything that requires the predictability of having fetched the data, must happen inside the callback (Edit: Or you may use promises or deferreds or etc.. but those are more complicated for what you are trying to do here). So that is why your console.log() inside the success callback works, and the one outside will probably never work.
Upvotes: 0
Reputation: 37701
It works in the outside function, but not right away because async calls take some time. That's the nature of JS.
The easiest way "out of it" is to move all the code that depends directly on the results of your async function into another function and then just run it from within the success callback.
Something like this:
function example() {
var post = object.get("owner");
post.fetch({
success: function(post) {
window.titles = post.get("username");
otherImportantCode(); // call the remaining code from here
}
});
console.log(window.titles); // won't work here
}
function otherImportantCode() {
console.log(window.titles); // see, it works here, outside the example function
// ... the rest of the code depending on window.titles
}
When you're ready for more advanced handling of such issues, learn about promises and events.
Upvotes: 0
Reputation: 69367
The post.fetch
function is asynchronous, this means that it needs a callback to call when it's finished, otherwise you'll never know when the function has been completed. Asynchronous functions run separately from the rest of the code.
When you call post.fetch
it start by its own and it will not stop the script, so right after calling post.fetch
, the next line of code is executed, which is actually console.log(window.titles)
. But window.titles
has not yet been defined, since that post.fetch
is still working.
When post.fetch
finishes working the given callback function gets executed, and then the window.titles
variable gets defined. So if you want to log window.titles
you have to put the console.log()
only inside the callback of post.fetch
.
Upvotes: 0
Reputation: 739
This is async call. The inner will be executed after the POST success. Meanwhile the outer execute after you start to send POST. The window.titles
is defined when the POST success
So the at the time outer call is executed, the window.titles
is undefined.
You should have look at this http://api.jquery.com/jquery.ajax/
Upvotes: 1