不,您不能从回调中产生(从技术上讲,它不是“内部函数”,这意味着其他东西)。显然没有办法用* 等价物调用forEach,或者,如果回调本身是一个生成器,则告诉forEach 用yield * 调用回调。
另一种方法是写一个函数forEachGen,如下:
function *forEachGen(array, fn) { for (var i of array) yield *fn(i); }
基本上将 for 循环移动到 forEachGen。定义一个小样本生成器为
function *yieldSelf(item) { yield item; }
forEachGen 将用作
yield *forEachGen(array, yieldSelf);
这假设回调本身是一个生成器,正如您在示例中所暗示的那样。如果回调是 ROF(常规旧函数),例如
function returnSelf(item) { return item; }
那就是
function *forEachGen(array, fn) { for (var i of array) yield fn(i); }
用作
yield *forEachGen(array, returnSelf);
如果您不介意将其添加到数组原型中,那么
Object.defineProperty(Array.prototype, 'forEachGen', { value :
function *(fn) { for (i of this) yield fn(i); }
});
然后做
yield *array.forEachGen(yieldSelf)
您可能对http://fitzgen.github.io/wu.js/ 感兴趣,它为生成器定义了一个包装器,包装器上有forEach 等方法。
async / await
使用await,您应该能够执行以下操作。
定义一个简单的回调,它只为自己返回一个承诺。
async function returnSelf(item) { return await item; }
forEachAsync 将输入数组映射到一个 Promise 数组,并使用 await * 为所有准备就绪的单个 Promise 创建并返回一个 Promise。
async function forEachAsync(values, fn) {
return await *values.map(returnSelf);
}
我们可以将结果视为常规承诺,并将其打印在 then 中:
forEachAsync([1,2,3], returnSelf) .
then(result => console.log(result);
或者使用一个小的 IIFE 异步包装器来等待结果然后打印出来:
(async function() {
console.log(await forEachAsync([1,2,3], returnSelf));
})();
测试使用
babel-node --experimental test.js