Use case - ES6.generator -- Internally Iterator with the capacity of interception.
function run(gen) {
var args = [].slice.call(arguments, 1),
it;
// initialize the generator in the current context
it = gen.apply(this, args);
// return a promise for the generator completing
return Promise.resolve()
.then(function handleNext(value) {
// run to the next yielded value
var next = it.next(value);
return (function handleResult(next) {
// generator has completed running?
if (next.done) {
return next.value;
} else {
return Promise.resolve(next.value)
.then(
// resume the async loop on
// success, sending the resolved
// value back into the generator
handleNext,
// if `value` is a rejected
// promise, propagate error back
// into the generator for its own
// error handling
function handleErr(err) {
return Promise.resolve(
it.throw(err)
)
.then(handleResult);
}
);
}
})(next);
});
}
function foo(x, y) {
return request(
"http://some.url.1/?x=" + x + "&y=" + y
);
}
function* main() {
try {
var text = yield foo(11, 31);
console.log(text);
} catch (err) {
console.error(err);
}
}
run(main);
function* fibonacci() {
let [prev, curr] = [0, 1];
while (true) {
let reset = yield prev;
[prev, curr] = reset ? [0, 1]: [curr, prev + curr];
}
}
var gen = fibonacci();
console.log(gen.next().value); // 0
console.log(gen.next().value); // 1
console.log(gen.next().value); // 1
console.log(gen.next().value); // 2
console.log(gen.next().value); // 3
console.log(gen.next().value); // 5
console.log(gen.next().value); // 8
console.log(gen.next(true).value); // 0
console.log(gen.next().value); // 1
console.log(gen.next().value); // 1
console.log(gen.next().value); // 2
function* g4() {
yield* [1, 2, 3];
return "foo";
}
var result;
function* g5() {
result = yield* g4();
}
var iterator = g5();
console.log(iterator.next()); // { value: 1, done: false }
console.log(iterator.next()); // { value: 2, done: false }
console.log(iterator.next()); // { value: 3, done: false }
console.log(iterator.next()); // { value: undefined, done: true },
// g4() returned { value: "foo", done: true } at this point
console.log(result); // "foo"
//------------------------ Example 2 ------------------------
function *foo() {
var r2 = yield request( "http://some.url.2" );
var r3 = yield request( "http://some.url.3/?v=" + r2 );
return r3;
}
function *bar() {
var r1 = yield request( "http://some.url.1" );
// "delegating" to `*foo()` via `yield*`
var r3 = yield *foo();
console.log( r3 );
}
run( bar );