I searched for real cases ES6 generators and didn't find proper explanation. I am trying to understand this first Promise scenario.
Let's say we have 2 rest apis: getUser and getUserComments
We wan't to create a linear code structure avoiding nested then callback functionalities. So ...
Define mocked apis
function getUser () {
return new Promise(function(resolve, reject) {
return setTimeout(function() { resolve({id: 1, label: 'John'}); }, 200);
});
}
function getUserComments(userId) {
return new Promise(function(resolve, reject) {
return setTimeout(function() {resolve({comments: 'comments', userId: userId}); }, 200);
});
}
Define generator
function* generator () {
yield getUser();
yield getUserComments(userId); // userId represents data from first request / first yield how should I pass it ?!
}
var g = generator();
var first = g.next(1);
var second = g.next(2);
How can I get the response from first yield (yield getUser()) and pass it to the next yield (yield getUserComments(userId)) ?
You could just assign yielded result to variable:
The next() method also accepts a value which can be used to modify the internal state of the generator. A value passed to next() will be treated as the result of the last yield expression that paused the generator. (From MDN, Advanced generators)
Then since you are dealing with Promises it makes sense to use async/await to unwrap it to value.
Try this (I corrected setTimeout parameters a bit):
async function getUser() {
return new Promise(function(resolve, reject) {
setTimeout(resolve, 0, {
id: 1,
label: 'John'
})
})
};
async function getUserComments(user) {
return new Promise(function(resolve, reject) {
setTimeout(resolve, 0, {
...user,
comments: 'comments',
}, 'userComments');
});
}
function* generator () {
const user = yield getUser();
yield getUserComments(user);
}
(async function () {
const g = generator();
const user = await g.next().value
const comments = await g.next(user).value
console.log(comments)
})()