我可以从内部函数中产生吗?
Can I yield from an inner function?
使用 ES6 生成器,我看到这样的代码:
var trivialGenerator = function *(array) {
var i,item;
for(var i=0; i < array.length; i++){
item = array[i];
yield item;
};
};
是否可以编写更类似于以下代码的内容?
var trivialGenerator = function *(array) {
array.forEach(function *(item){
yield item;
});
};
不,您不能在内部函数中使用yield
。但在你的情况下,你不需要它。您始终可以使用循环for-of
而不是forEach
方法。它看起来会更漂亮,你可以在里面使用 continue
、break
、 yield
:
var trivialGenerator = function *(array) {
for (var item of array) {
// some item manipulation
yield item;
}
}
如果您对其中的项目进行了一些操作,则可以使用 for-of
。否则,您绝对不需要创建此生成器,因为array
本机具有iterator
接口。
不,你不能从回调中产生(从技术上讲,它不是一个"内部函数",这意味着别的东西(。显然没有办法用等效的 *
调用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);
这假设回调本身是一个生成器,正如您在示例中似乎暗示的那样。如果回调是 WOO(常规旧函数(,例如
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
将输入数组映射到一个承诺数组,并使用await *
为所有准备就绪的单个承诺创建和返回承诺。
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
但你可以创建自己的包装器来将函数转换为生成器。这是我是如何做到的:
export async function* createListFilesIterator(
worker: DriveWorker,
): AsyncGenerator<FilesResp, void, unknown> {
const messages: FilesResp[] = [];
let processed = 0;
let waited = 0;
let done = false;
worker.onmessage = (msg) => {
const { data: evt } = msg;
if (evt.type === "files") {
messages.push(evt);
} else if (evt.type === "done") {
done = true;
}
};
while (processed < messages.length || (!done && waited <= 16)) {
if (processed < messages.length) {
yield messages[processed];
waited = 0;
processed += 1;
} else {
waited += 1;
await new Promise((resolve) => {
setTimeout(resolve, 1000 * waited * 0.5);
});
}
}
}
使用此方法,我可以将我的 worker 实例转换为迭代器,我可以循环使用:
for await (const evt of createListFilesIterator(worker)) {
...
当然,我可以通过返回一个带有onmessage事件侦听器的承诺来使它更简单,但我只是想看看这是否可行/有意义。我认为当您超过两种返回类型时,生成器会变得比事件侦听器更干净、更易于使用。但这是我的意见,当然。
- 我可以在json对象中添加一个函数吗
- AngularJS:我可以跳过函数参数回调吗
- 我可以将函数导入到typescript类文件中吗
- 为什么我可以't直接将console.log()设置为回调函数
- 我可以从内部函数中产生吗?
- 我可以将哪些事件附加到jQuery's on()函数
- Chrome扩展和Angular:我可以把Chrome.runtime.sendMessage变成一个同步函数吗
- 我可以将javascript绘制函数更改为图像吗
- 使用角度图时,我可以用函数定义数据点颜色吗
- 我可以在javascript中的回调函数中为变量赋值吗
- 我可以获得用Ajax调用的函数的返回代码吗
- 为什么可以't我从hamsters.js内部运行我的方法
- 当数组中的某个函数没有返回promise时,我可以使用$q.all吗
- JavaScript 新手:我可以将列表传递到这个函数中并让它仍然工作吗?
- 我可以通过使用函数绑定来保留默认值吗?如果没有,为什么
- 我可以在 TypeScript 中扩展函数吗?
- 我可以将变量传递给内部定义的函数吗?
- 为什么我可以从onblr这样的事件内部调用javascript函数,但当我调用<身体>它变成'未定义
- 为什么我的内部内部函数可以访问外部全局作用域变量?这是不是违反了作用域/闭包
- 为什么不't我的内部函数可以访问在其父函数中定义的对象变量