Как сделать итерируемый метод класса?

Он говорит мне: «TypeError: Foo.my_method(...) не является функцией или ее возвращаемое значение не является асинхронным итерируемым». Как сделать так?

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)
    }
})

Просто исправьте то, что вы ввели как .... Если этого объяснения недостаточно, то используйте не ..., а минимально воспроизводимый пример.

VLAZ 31.03.2023 16:57

Теперь это воспроизводимо

rigiva 31.03.2023 17:03
constructor() { return (async () => { this.sleep(1000) })() } было СУПЕР ВАЖНО! Ваш первоначальный код был похож на то, как вы пришли к автомеханику и сказали: «Кажется, у моей машины проблемы с запуском». И ты не показываешь машину, просто рассказываешь ему, что ты пробовал. Зарядка аккумулятора, замена масла, ходовая диагностика. Но опуская тот факт, что это была не машина, а кусок сыра, с которым вы пытались это сделать. Который на самом деле не работает, как автомобиль. Или вообще. Потому что вы переопределили конструктор, чтобы он возвращал что-то, что не является экземпляром вашего класса.
VLAZ 31.03.2023 17:31

да, извини, я был таким глупым

rigiva 31.03.2023 17:38
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
5
51
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

метод this.my = асинхронная функция(){...}

Попробуйте так

Теперь он кричит на мою доходность с помощью «SyntaxError: неожиданное зарезервированное слово строгого режима»

rigiva 31.03.2023 16:50

Асинхронные функции не являются итерируемыми.

VLAZ 04.04.2023 20:14
Ответ принят как подходящий

Делает

let foo = new Foo().then(

установит foo как Promise, поэтому вы не можете сделать foo.my_method()

Я думаю, что вы пытаетесь сделать следующее:

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.info(msg)
})()

Я только что добавил условие в while, чтобы ваш генератор завершал работу в какой-то момент, и я поместил асинхронный цикл в (асинхронный) IFEE, чтобы генератор можно было ожидать напрямую (похоже, это то, что вы пытались делать).

Это работает для вас? Дайте мне знать, если это имеет смысл.

Мне нужно подождать, пока конструктор закончит свою работу, это занимает некоторое время, похоже, это мой настоящий вопрос

rigiva 31.03.2023 17:18

Я не думаю, что имеет смысл писать конструктор, который нужно ждать. Если вам нужно дождаться данных, прежде чем вы сможете создать экземпляр объекта, сделайте это, то есть fetch().then(data => new Foo(data)). Это даст вам больше гибкости и не привязывает ваш класс к тому, как вы извлекаете его данные.

Moritz Ringler 31.03.2023 17:19

Хорошо, спасибо, я переместил все долгоиграющие вещи в другой метод инициализации, и теперь он работает.

rigiva 31.03.2023 17:32

@rigiva «Мне нужно подождать, пока конструктор закончит свою работу, это занимает некоторое время, похоже, это мой настоящий вопрос» Да, это называется XY-проблема.

VLAZ 31.03.2023 17:33

возвращать асинхронную функцию из конструктора нельзя. в чистом js это что-то сделало бы (вообще бесполезно в примере из вопроса), но ts просто не позволит этому случиться, не поставив any fo типа.

Я думаю, вы реализуете какую-то коллекцию, и это способ сделать асинхронную итерируемую коллекцию.

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.info(msgs);
}

объявив Symbol.asyncIterator в классе, все экземпляры будут асинхронно повторяемыми

Другие вопросы по теме