Как я могу избежать вложенных обещаний в этом случае - PullRequest
0 голосов
/ 24 марта 2020

Как я могу заставить этот фрагмент соответствовать правилам eslint или сделать его более читабельным / элегантным без вложенных обещаний?

class Sync {
  io = IO.getInstance();

  constructor(token) {
    this.token = token;
  }
  
  sendMessage = (
    data,
    retryTimeout = 0,
  ) => {
    const response = this.io.request(requestConfig); // should return a Promise
    const timeout = retryTimeout + 3000;
    // want to retry when AJAX error
    return response
      .catch(() => new Promise((resolve, reject) => {
        if (this.token === data.token) {
          // eslint warning: Avoid nesting promises.eslint(promise/no-nesting)
          setTimeout(() => this.sendMessage(data, timeout).then(resolve, reject), timeout);
        } else {
          reject(new Error('Failed to send message due to network offline'));
        }
      }));
  }
}

class Sync {
  async sendMessage(data, retryTimeout = 0) {
    const timeout = retryTimeout + 3000;
    try {
      await this.io.request(requestConfig); // should return a Promise
    } catch(e) {
      if (this.token === data.token) {
        await new Promise(resolve => {
          setTimeout(resolve, timeout);
        });
        return this.sendMessage(data, timeout);
      } else{
        throw new Error('Failed to send message due to network offline');
      }
    }
  }
Я пытался изменить это на async функцию, все в порядке сейчас? или как мне сделать это правильно?

Спасибо.

1 Ответ

0 голосов
/ 24 марта 2020

Использование .then(resolve, reject) является конструктором Promise antipattern . Вместо этого добавьте:

class Sync {
  sendMessage(data, retryTimeout = 0) {
    const response = this.io.request(requestConfig); // should return a Promise
    const timeout = retryTimeout + 3000;
    // want to retry when AJAX error
    return response.catch(() => {
      if (this.token === data.token) {
        return new Promise(resolve => {
          setTimeout(resolve, timeout);
        }).then(() => this.sendMessage(data, timeout));
      } else {
        throw new Error('Failed to send message due to network offline');
      }
    });
  }

Еще лучше, если вы реорганизуете new Promise(…) с setTimeout в вспомогательную функцию delay.

...