Reputation: 270
I am trying to wrap my head around JS generators but I don't understand why the sample async operations below return undefined.
I thought the whole point of the yield was to wait for async calls to complete.
function getUsers(){
var users;
$.ajax({
url: 'https://jsonplaceholder.typicode.com/users/'
}).then(function(users) {
console.log(gen.next(users));
});
}
function getPosts(){
var posts;
$.ajax({
url: 'https://jsonplaceholder.typicode.com/posts/'
}).then(function(posts) {
console.log(gen.next(posts));
});
}
function getComments(){
var comments;
$.ajax({
url: 'https://jsonplaceholder.typicode.com/comments/'
}).then(function(comments) {
console.log(gen.next(comments));
});
}
function* myGenerator() {
var users = yield getUsers();
var posts = yield getPosts();
var comments = yield getComments();
return ([users, posts, comments]);
}
var gen = myGenerator();
gen.next();
// {value: undefined, done: false} ---> why undefined here?
// {value: undefined, done: false} ---> why undefined here?
// {value: Array(3), done: true} ---> YAY, array DOES contains expected data
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Can anyone shine some light on that? Thank you!
Upvotes: 1
Views: 106
Reputation: 92440
So with the edit things work a little different. In every case except the last, your generator is yielding the result of your function which is undefined because your functions don't return anything.
However, when you call next()
from inside the the then()
s you are passing the result of the ajax promise to the generator. The generator receives that value, and save it in a variable (users
, posts
, etc). But it still returns undefined because the value of yield getPosts()
is undefined since the function doesn't return anything.
The last call to next()
happens in the then()
of getComments()
. Now the generator is out of values, so it returns {done: true}
and the values you have asynchronously been putting in variables. It returns those and your done.
This would all be much easier if you just did:
function getUsers(){
return $.ajax({
url: 'https://jsonplaceholder.typicode.com/users/'
})
}
getUsers().then(console.log)
Upvotes: 1
Reputation: 270
I think I understand and I am starting to see how this could be useful. I wrapped getUsers in a promise and get the expected value now! Thank you guys.
function getUsers(){
return new Promise((resolve) => {
$.ajax({
url: 'https://jsonplaceholder.typicode.com/users/'
}).then(function(users) {
resolve(gen.next(users));
});
});
}
Upvotes: 0