I've been studying Promises and Generators but I got stuck in the script below:
function getFile(file) {
return new Promise(function (resolve) {
fakeAjax(file, resolve);
});
}
function* getFiles() {
var p1 = getFile('file1');
var p2 = getFile('file2');
var p3 = getFile('file3');
output(yield p1);
output(yield p2);
output(yield p3);
}
function runner(gen) {
var g = gen();
function run(val) {
val || undefined;
var next = g.next(val);
if(!next.done && !next.value !== undefined) {
next.value
.then(function(v) {
run(v);
});
}
}
run();
}
runner(getFiles);
What I'm trying to figure it out is what happens when I get to the first yield on getFiles? Why does this code work, I don't get it.
*EDIT: output is simply a console.log wrappend in a function. The fakeAjax function returns a text from an object based on the 'file' requested.
What I'm trying to figure it out is what happens when I get to the first yield on getFiles? Why does this code work, I don't get it.
yield
does three things:
next()
will receive in the value
property. In this case, that's the promises you made.next()
. That will be the file name you passed as a argument to next()
.yield
is like a two-way conduit, both accepting values and passing values.
In your code at the first yield
it will return the object with the promise and pause, but it doesn't log anything to the console at this point — yield
can pause mid-expression. When you call next()
again it will finish the console.log and then move to the next yield
. It can be a little confusing because there is usually one more call to next
that there are yields
. For example in this code `next is called four times and that's why you get the last console.log.
Here's an MCVE that I assume approximates the undefined functions in your example:
function getFile(file) {
return new Promise(resolve => setTimeout(() => resolve(file), 1000))
}
function* getFiles() {
var p1 = getFile('file1');
var p2 = getFile('file2');
var p3 = getFile('file3');
console.log(yield p1); // return promise, then pause, then log value passed to next()
console.log(yield p2);
console.log(yield p3);
}
function runner(gen) {
var g = gen();
function run(val) {
var next = g.next(val);
if(!next.done && !next.value !== undefined) {
next.value
.then(function(v) {
run(v);
});
}
}
run();
}
runner(getFiles);