关键字在内部工作的方式yield
是创建一个状态机。您可以自己创建一个,或者如果列表不是太大并且您可以合理地将其保存在内存中,您可以简单地返回并使用一个列表,例如:
function getRecursively(...startingObjects:TargetObject[] ):TargetObject[]
{
var toreturn = [];
for (var key in startingObjects)
{
var startingObject = startingObjects[key];
toreturn.push(startingObject);
if (startingObject.InnerObjects != null)
for (var key2 in startingObject.InnerObjects){
var innerObject = startingObject.InnerObjects[key2];
var superInner = getRecursively(innerObject);
for (var key3 in superInner)
toreturn.push(superInner[key3]);
}
}
return toreturn;
}
如果你真的想要产量,你可以使用 google traceur 编译器:https ://github.com/google/traceur-compiler例如
function* cool() {
yield 123;
yield 456;
}
for (n of cool()) {
console.log(n);
}
在线尝试
如您所见,生成的状态机并非微不足道。
var $__generatorWrap = function(generator) {
return $traceurRuntime.addIterator({
next: function(x) {
switch (generator.GState) {
case 1:
throw new Error('"next" on executing generator');
case 3:
throw new Error('"next" on closed generator');
case 0:
if (x !== undefined) {
throw new TypeError('Sent value to newborn generator');
}
case 2:
generator.GState = 1;
if (generator.moveNext(x, 0)) {
generator.GState = 2;
return {
value: generator.current,
done: false
};
}
generator.GState = 3;
return {
value: generator.yieldReturn,
done: true
};
}
},
'throw': function(x) {
switch (generator.GState) {
case 1:
throw new Error('"throw" on executing generator');
case 3:
throw new Error('"throw" on closed generator');
case 0:
generator.GState = 3;
throw x;
case 2:
generator.GState = 1;
if (generator.moveNext(x, 1)) {
generator.GState = 2;
return {
value: generator.current,
done: false
};
}
generator.GState = 3;
return {
value: generator.yieldReturn,
done: true
};
}
}
});
};
function cool() {
var $that = this;
var $arguments = arguments;
var $state = 0;
var $storedException;
var $finallyFallThrough;
var $G = {
GState: 0,
current: undefined,
yieldReturn: undefined,
innerFunction: function($yieldSent, $yieldAction) {
while (true) switch ($state) {
case 0:
this.current = 123;
$state = 1;
return true;
case 1:
if ($yieldAction == 1) {
$yieldAction = 0;
throw $yieldSent;
}
$state = 3;
break;
case 3:
this.current = 456;
$state = 5;
return true;
case 5:
if ($yieldAction == 1) {
$yieldAction = 0;
throw $yieldSent;
}
$state = 7;
break;
case 7:
$state = -2;
case -2:
return false;
case -3:
throw $storedException;
default:
throw "traceur compiler bug: invalid state in state machine: " + $state;
}
},
moveNext: function($yieldSent, $yieldAction) {
while (true) try {
return this.innerFunction($yieldSent, $yieldAction);
} catch ($caughtException) {
$storedException = $caughtException;
switch ($state) {
default:
this.GState = 3;
$state = -2;
throw $storedException;
}
}
}
};
return $__generatorWrap($G);
}
for (var $__0 = $traceurRuntime.getIterator(cool()), $__1; !($__1 = $__0.next()).done;) {
n = $__1.value;
{
console.log(n);
}
}