如何创建可迭代类方法?

huangapple go评论119阅读模式
英文:

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 &lt; message.length) {
      yield await this.sleep(100).then(() =&gt; message.charAt(pos))
      pos += 1
    }
  }
  
  sleep(ms) {
        return new Promise(resolve =&gt; setTimeout(resolve, ms));
    }
}

(async function(){
  let foo = new Foo()
  await foo.load()
  
  const msg = []
  for await (const data of foo.my_method(&quot;ABCD&quot;)) {
      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 =&gt; setTimeout(resolve, ms));
    }
}

async function userCode() {
    let foo = new Foo(&#39;xxx&#39;);
    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

huangapple
  • 本文由 发表于 2023年3月31日 22:43:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/75899835.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定