Вызов метода класса JavaScript синхронно - PullRequest
0 голосов
/ 12 февраля 2019

Я создаю пакет с JavaScript, который имеет две функции: init и sendData.

class Client {
   init() {
     return axios.post(this.baseUrl).then((response) => {
       this.token = response.data.token
     })
   }

   sendData() {
     return axios.post(this.baseUrl, {token: this.token})
   }
}

Метод init необходимо вызвать перед методом sendData, так каквозвращает токенЕсть ли способ ожидания вызова метода init перед вызовом метода sendData?

Ответы [ 2 ]

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

Асинхронная инициализация - хороший пример использования фабричного шаблона.Вместо того, чтобы выполнять асинхронную работу после создания класса, делайте это раньше и сохраняйте конструктор синхронным.По моему мнению, синхронный конструктор, который выполняет простое присваивание, имеет наименьший «запах» и является самым простым для тестирования.

class Client {

   constructor(baseUrl, token) {
      this.baseUrl = baseUrl;
      this.token = token;
   }

   async create(baseUrl) {
     const response = await axios.post(baseUrl);
     return new Client(baseUrl, response.data.token);
   }

   async sendData() {
     return axios.post(this.baseUrl, {token: this.token})
   }
}

...

const client = await Client.create('http://foo.com');
const response = await client.sendData();
0 голосов
/ 12 февраля 2019

Вам нужен потребитель вашего API для этого?

// within an async function
const client = new Client();
await client.init();
await client.sendDate();

// or anywhere just using promises
const client = new Client();
client.init().then(() => client.sendDate());

или сам API?

// definition
class Client {
   async init() {
     const response = await axios.post(this.baseUrl);
     this.token = response.data.token;
   }

   async sendData() {
     await this.init(); // call init before sending data
     return axios.post(this.baseUrl, {token: this.token})
   }
}

// usage somewhere in an async function
const client = new Client();
client.sendDate() // calls init, then sends the data

Возможно, удалите лишние вызовы, если токен не изменяется?

class Client {
   async init() {
     const response = await axios.post(this.baseUrl);
     this.token = response.data.token;
   }

   async sendData() {
     if (!this.token) { // now you'll only call init for missing token
       await this.init();
     }
     return axios.post(this.baseUrl, {token: this.token})
   }
}

// usage somewhere in an async function
const client = new Client();
await client.sendDate(); // calls init (only the first time), then sends the data

Обратите внимание, что функции, возвращающие обещание, по своей сути асинхронны, поэтому нет способа получить их результат синхронным способом.Однако мы можем написать асинхронный код, используя async / await, чтобы он синтаксически выглядел (почти) идентично синхронной версии.

...