Должен ли я создать новый Promise в каждом методе класса? - PullRequest
0 голосов
/ 06 февраля 2019

Я хотел бы использовать Обещания в моих методах класса.В Антипаттернах Promise я читал, что создание нового обещания для каждой новой функции считается плохим.

Однако я не хочу возвращать несвязанные обещания в моем проекте, поэтомуЯ думал о том, чтобы сделать что-то вроде этого:

class MyClass {

  async getToken() {
    return new Promise(
      (resolve, reject) => {
        // . . .
        const token_str = '<response_from_http_request>';
        resolve(token_str);
      }
    )
  }

  async doSomething(token) {
    return new Promise(
      (resolve, reject) => {
        const result = // . . .
        resolve(result);
      }
    )
  }

  async doAnotherSomething(token) {
    return new Promise(
      (resolve, reject) => {
        const result = // . . .
        resolve(result);
      }
    )
  }

}

Тогда я бы использовал это так:

let instance = new MyClass();

(async () => {
    const token = await instance.getToken();

    const result1 = await instance.doSomething(token);
    console.log(result1);

    const result2 = await instance.doAnotherSomething(token);
    console.log(result2);

})();

Это похоже на правильный способ сделать это, или это антипаттернтоже?И если так, как я могу избежать написания такого кода?


РЕДАКТИРОВАТЬ: Что если мне нужно сделать несколько последовательных http-вызовов, выполнить некоторые действия с результатами и затем вернутьОбещание на его основе?

Насколько я понимаю, если я не сделаю новое Обещание, я должен вернуть то, что было сделано библиотекой got.js, которая включает в себяданные ответа http.

Вместо этого я хочу вернуть Promise, который содержит результат моего метода класса.

Пример:
  async getCityWeather( city_name ) {
    return new Promise(
      (resolve, reject) => {

        // get the city id based on its name
        const city_id = await got(`https://my-api/getCityIdByName/${city_name}`);

        // now get the weather info for the city with id `cityid`
        const weather_info = await got(`https://my-api/weatherById/${city_id}`);

        // make an object to return
        const temperature = {
          weather_info.temp_min,
          weather_info.temp_max,
        }

        resolve(temperature);

        // ... all error handling are omitted

      }
    )
  }

Я не хочу возвращать Promise, содержащий got.js возвращаемые значения, я хочу вернуть мои значения, основанные на вызовах http-запроса.

1 Ответ

0 голосов
/ 06 февраля 2019

async функции всегда возвращают Promise.

Функция / метод возвращает Promise при следующих обстоятельствах:

  • Вы явно указалисоздал и вернул Обещание из его тела.
  • Вы вернули Обещание, существующее вне метода.
  • Вы пометили его как async.

Поскольку выможет await Promise, а instance.doSomething уже является асинхронно-помеченным методом, вы можете ожидать его без необходимости явного возврата Promise.

Просто return это результат, как в обычном синхронном методе.

Я не хочу возвращать несвязанные обещания в моем проекте ...

Если вы на самом деле не делаете что-то асинхронное в вашем методе (доступ к файловой системе, вызовы базы данных, таймеры и т. Д.), Вам не нужно оборачивать это в Promise или await это когда вам нужен результат.

Самый обычный случай, когда вам действительно нужно что-то обернуть в Promise, это если у вас есть асинхронная функция, которая работает с использованием обратных вызовов , но вы хотите использовать его как Promise.

// plain old callback-style asynchronous functions:
const getFooViaCallback = callback => {
  setTimeout(() => {
    callback('foo')
  }, 150)
}

const getBarViaCallback = callback => {
  setTimeout(() => {
    callback('bar')
  }, 150)
}

class Foo {
  constructor() {}
  
  getFooViaPromise() {
    // wrap callback-style code in a Promise
    // so we can await it.
    return new Promise(resolve => {
      getFooViaCallback(result => {
        resolve(result)
      })
    })
  }

  getBarViaPromise() {
    // wrap callback-style code in a Promise
    // so we can await it.
    return new Promise(resolve => {
      getBarViaCallback(result => {
        resolve(result)
      })
    })
  }
  
  getBaz() {
    // no reason to wrap this in a Promise,
    // since it's a synchronous method.
    return 'baz'
  }
  
  async getFooBarBaz() {
    const foo = await this.getFooViaPromise()
    const bar = await this.getBarViaPromise()
    const baz = this.getBaz()

    return foo + ',' + bar + ',' + baz
  }
}

;(async() => {
  const foo = new Foo()
  
  const result = await foo.getFooBarBaz()
  console.log('foo.getFooBarBaz() result: ', result)
})()

Для краткости я пропустил обработку ошибок в приведенном выше фрагменте, но вы должны использовать throw в async отмеченных методах для выявления ошибок.Это эквивалент звонка .reject() в Обещании.

...