英文:
How to make iterable class method?
问题
It's telling me "TypeError: Foo.my_method(...) is not a function or its return value is not async iterable". How to make it so?
class Foo {
constructor() {
return (async () => { this.sleep(1000) })()
}
async *my_method(message) {
let pos = 0
while (true) {
yield message.charAt(pos)
await this.sleep(100)
pos += 1
}
}
sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
}
let foo = new Foo().then(async () => {
for await (let msg of foo.my_method("AAAA")) {
msgs.push(msg)
}
})
英文:
It's telling me "TypeError: Foo.my_method(...) is not a function or its return value is not async iterable". How to make it so?
class Foo {
constructor() {
return (async () => { this.sleep(1000) })()
}
async *my_method(message) {
let pos = 0
while (true) {
yield message.charAt(pos)
await this.sleep(100)
pos += 1
}
}
sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
}
let foo = new Foo().then(async () => {
for await (let msg of foo.my_method("AAAA")) {
msgs.push(msg)
}
})
答案1
得分: 0
Doing
will set foo to be a Promise, which is why you couldn't do foo.my_method()
I think what you are trying to do is this:
class Foo {
load(){
return Promise.resolve()
}
async *my_method(message) {
let pos = 0
while (pos < message.length) {
yield await this.sleep(100).then(() => message.charAt(pos))
pos += 1
}
}
sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
}
(async function(){
let foo = new Foo()
await foo.load()
const msg = []
for await (const data of foo.my_method("ABCD")) {
msg.push(data)
}
console.log(msg)
})()
I have just added a condition on the while
so that your generator terminates at some point, and I put the async loop into an (async) IIFE, so that the generator can be awaited directly (it looks like this is what you were trying to do).
Does that work for you? Let me know if it makes sense.
英文:
Doing
let foo = new Foo().then(
will set foo to be a Promise, which is why you couldn't do foo.my_method()
I think what you are trying to do is this:
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
class Foo {
load(){
return Promise.resolve()
}
async *my_method(message) {
let pos = 0
while (pos < message.length) {
yield await this.sleep(100).then(() => message.charAt(pos))
pos += 1
}
}
sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
}
(async function(){
let foo = new Foo()
await foo.load()
const msg = []
for await (const data of foo.my_method("ABCD")) {
msg.push(data)
}
console.log(msg)
})()
<!-- end snippet -->
I have just added a condition on the while
so that your generator terminates at some point, and I put the async loop into an (async) IFEE, so that the generator can be awaited directly (it looks like this is what you were trying to do).
Does that work for you? Let me know if it make sense.
答案2
得分: 0
从构造函数返回异步函数不可行。在纯JavaScript中,它会执行某些操作(在问题示例中并不特别有用),但TypeScript不会允许这种情况发生,除非将类型设置为any
。
我认为您正在实现某种集合,这是创建异步可迭代集合的方法:
通过在类上声明Symbol.asyncIterator
,所有实例都将成为异步可迭代对象。
英文:
returning async function from the constructor is not ok. in pure js it would do something (not useful at all in the example from the question), but ts just won't allow that to happen without puting any
fo the type.
I think you are implementing some kind of collection and this is the way to make async iterable collection
class Foo {
constructor(private message: string) {}
async *[Symbol.asyncIterator]() {
let pos = 0
while (this.message[pos]) {
yield this.message.charAt(pos)
await this.sleep(100)
pos += 1
}
}
sleep(ms: number) {
return new Promise(resolve => setTimeout(resolve, ms));
}
}
async function userCode() {
let foo = new Foo('xxx');
const msgs = [];
for await (let msg of foo) {
msgs.push(msg)
}
console.log(msgs);
}
by declaring Symbol.asyncIterator
on the class, all instances would be async iterable
答案3
得分: -2
this.my_method = async function(){...}
尝试像这样
英文:
this.my_method = async funtion(){...}
Try like this
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论