【发布时间】:2015-05-30 13:42:52
【问题描述】:
我很难理解生成器。但我认为我正在尝试做的应该是可能的。
我有一个对象Topic 可以访问Pages。最初Topic 的实现是为了通过回调来检索Pages。
var Topic = function( id ) {
var repository = new PageRepository();
this.id = id;
this.getAllPages = function( callback ) {
repository.getAllPagesByTopicId( this.id, function( result ) {
var pages = [];
while( result.hasNext() ) {
pages.push( result.next() );
}
callback( pages );
} );
}
}
var topic = new Topic( 1 );
topic.getAllPages( function( pages ) {
console.log( pages ) // received Page instances
} );
现在,假设我无法重构 PageRepository 的回调机制,但我确实想重构 Topic 以便我可以通过生成器访问它的页面,而不是通过打回来。这是否可行,没有太多的麻烦?
我知道我可以使用 for...of 语句迭代生成器值,例如:
var topic = new Topic( 1 );
for( let page of topic.pages() ) { // create the generator
console.log( page ); // received next Page
}
...所以我想出了以下内容:
var Topic = function( id ) {
...
this.pages = function*() { // refactored getAllPages () to a generator function pages()
repository.getAllPagesByTopicId( this.id, function( result ) {
while( result.hasNext() ) {
yield result.next(); // yield the next Page
}
} );
}
}
但是,这不起作用,可能是因为在回调中调用了yield。
然后,基于我对this article(从“使用生成器......”开始)的(较差的)理解,我认为这可能有效:
var Topic = function( id ) {
...
this.pages = function*() {
let gen = function*() {}(); // create an inner generator
// not actually sure why the following wrapper function is needed
// but something similar is used in mentioned article
yield function() {
repository.getAllPagesByTopicId( this.id, function( result ) {
while( result.hasNext() ) {
gen.next( result.next() ); // call next() on inner generator
}
} );
}(); // immediately create this mysterious wrapper function
}
}
不幸的是,这也不起作用。
所以,我想要实现的目标是可行的,没有太多麻烦;含义:没有模块(如 co、suspend 等)和/或复杂的 thunk 生成器,你有什么?
【问题讨论】:
标签: javascript asynchronous callback generator ecmascript-6