Обновить объект после возврата функции

#javascript

#javascript

Вопрос:

Я пытаюсь создать простой Api-сервис, использующий JavaScript. У этой службы есть 3 свойства (загрузка, данные, ошибка), и я хочу динамически изменять значения этих свойств в promise, и я хочу использовать эту службу таким образом ->

 const { loading, data, err } = new ApiService().send(request).getResults();
  

Моя главная цель — динамическая загрузка и данные, поэтому во время вызова Api значение свойства загрузки равно true, а когда вызов Api завершен, значение свойства загрузки равно false, а свойство data заполнено ответом Api. Итак, я хочу использовать этот сервис таким образом ->

   const { loading, data, err } = new ApiService().setSync(false).send(q).getResults();
  if (loading) {
     pElement.text("Loading");
  } else {
     pElement.text(data.id);
  }
  

Мои служебные коды Api:

 function ApiService(header = {}) {
    this._loading = false;
    this._data = {};
    this._header = header;
    this._error = "";
    this._isAsync = false;
}

ApiService.prototype.setSync = function (isAsync = false) {
    this._isAsync = isAsync;
    return this;
};

ApiService.prototype.send = function (request) {
    const self = this;
    if (!this._isAsync) {
      this._loading = true;
      request
      .then(function (data) {
          self._loading = false;
          self._data = data;
      })
      .catch(function (e) {
          self._error = e;
      });

      return this;
      } else {
          return request
                 .then(function (data) {
                      self._loading = false;
                      self._data = data;
                      return data;
                   })
                   .catch(function (e) {
                      self._error = e;
                   });
      }
 };

 ApiService.prototype.getResults = function () {
     const self = this;
     return { loading: self._loading, data: self._data, err: self._error };
 };

 module.exports = ApiService;
  

Эта служба работает один раз, и она возвращает значения по умолчанию как обычно, но я хочу динамическое обновление значений. Возможно ли это?

Ответ №1:

Короткий ответ: Нет. После оператора return вы не можете обновить значения, которые вы имеете в виду.

Такие фреймворки, как React.js у них есть подобный синтаксис в их API Hooks, но у них также есть компоненты, которые выполняются снова каждый раз при изменении состояния, что приводит к переоценке переменных.

В ванильной среде JS проще всего вернуть обещание, дождаться его завершения, а затем продолжить. Я думаю, что использование async / await — это самое близкое к тому, чтобы ваш код вел себя так, как вам хотелось бы.

Приведенный ниже фрагмент демонстрирует, как это будет выглядеть и выполняться. Возвращаемое loading значение всегда будет false таким, каким вы получите результат только после завершения загрузки, поэтому его можно опустить.

 function ApiService(header = {}) {
    this._loading = false;
    this._data = {};
    this._header = header;
    this._error = "";
    this._isAsync = false;
}
  
ApiService.prototype.send = async function(request) {
  this._loading = true;
  this._data = {};
  this._error = "";
  try {
    const data = await request();
    this._data = data;
  } catch(error) {
    this._error = error;
  } finally {
    this._loading = false;
    return { 
      data: this._data, 
      error: this._error, 
    };
  }
}
  
 (async () => {
  pElement.text("Loading");
  const { data, err } = await new ApiService().send(request);
  if (!err) {
    pElement.text(data.id);
  }
})();
  

Комментарии:

1. Спасибо за ваш ответ. Я знаю, как это сделать в контексте React, но я хочу сделать это в ванильном JavaScript, но, насколько я понимаю, мне нужно создать оболочку для повторного отображения функции. Поэтому я отказываюсь от этой функции, потому что я не могу поддерживать эту оболочку.